@hasna/terminal 2.0.5 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +52 -21
- package/package.json +1 -1
- package/src/ai.ts +77 -130
- package/src/cli.tsx +51 -21
- package/src/command-validator.ts +11 -0
- package/src/context-hints.ts +291 -0
- package/src/discover.ts +238 -0
- package/src/economy.ts +53 -0
- package/src/output-processor.ts +7 -18
- package/src/output-store.ts +65 -0
- package/src/providers/base.ts +3 -1
- package/src/providers/groq.ts +108 -0
- package/src/providers/index.ts +26 -2
- package/src/providers/providers.test.ts +4 -2
- package/src/providers/xai.ts +108 -0
- package/src/sessions-db.ts +81 -0
- package/temp/rtk/.claude/agents/code-reviewer.md +221 -0
- package/temp/rtk/.claude/agents/debugger.md +519 -0
- package/temp/rtk/.claude/agents/rtk-testing-specialist.md +461 -0
- package/temp/rtk/.claude/agents/rust-rtk.md +511 -0
- package/temp/rtk/.claude/agents/technical-writer.md +355 -0
- package/temp/rtk/.claude/commands/diagnose.md +352 -0
- package/temp/rtk/.claude/commands/test-routing.md +362 -0
- package/temp/rtk/.claude/hooks/bash/pre-commit-format.sh +16 -0
- package/temp/rtk/.claude/hooks/rtk-rewrite.sh +70 -0
- package/temp/rtk/.claude/hooks/rtk-suggest.sh +152 -0
- package/temp/rtk/.claude/rules/cli-testing.md +526 -0
- package/temp/rtk/.claude/skills/issue-triage/SKILL.md +348 -0
- package/temp/rtk/.claude/skills/issue-triage/templates/issue-comment.md +134 -0
- package/temp/rtk/.claude/skills/performance.md +435 -0
- package/temp/rtk/.claude/skills/pr-triage/SKILL.md +315 -0
- package/temp/rtk/.claude/skills/pr-triage/templates/review-comment.md +71 -0
- package/temp/rtk/.claude/skills/repo-recap.md +206 -0
- package/temp/rtk/.claude/skills/rtk-tdd/SKILL.md +78 -0
- package/temp/rtk/.claude/skills/rtk-tdd/references/testing-patterns.md +124 -0
- package/temp/rtk/.claude/skills/security-guardian.md +503 -0
- package/temp/rtk/.claude/skills/ship.md +404 -0
- package/temp/rtk/.github/workflows/benchmark.yml +34 -0
- package/temp/rtk/.github/workflows/dco-check.yaml +12 -0
- package/temp/rtk/.github/workflows/release-please.yml +51 -0
- package/temp/rtk/.github/workflows/release.yml +343 -0
- package/temp/rtk/.github/workflows/security-check.yml +135 -0
- package/temp/rtk/.github/workflows/validate-docs.yml +78 -0
- package/temp/rtk/.release-please-manifest.json +3 -0
- package/temp/rtk/ARCHITECTURE.md +1491 -0
- package/temp/rtk/CHANGELOG.md +640 -0
- package/temp/rtk/CLAUDE.md +605 -0
- package/temp/rtk/CONTRIBUTING.md +199 -0
- package/temp/rtk/Cargo.lock +1668 -0
- package/temp/rtk/Cargo.toml +64 -0
- package/temp/rtk/Formula/rtk.rb +43 -0
- package/temp/rtk/INSTALL.md +390 -0
- package/temp/rtk/LICENSE +21 -0
- package/temp/rtk/README.md +386 -0
- package/temp/rtk/README_es.md +159 -0
- package/temp/rtk/README_fr.md +197 -0
- package/temp/rtk/README_ja.md +159 -0
- package/temp/rtk/README_ko.md +159 -0
- package/temp/rtk/README_zh.md +167 -0
- package/temp/rtk/ROADMAP.md +15 -0
- package/temp/rtk/SECURITY.md +217 -0
- package/temp/rtk/TEST_EXEC_TIME.md +102 -0
- package/temp/rtk/build.rs +57 -0
- package/temp/rtk/docs/AUDIT_GUIDE.md +432 -0
- package/temp/rtk/docs/FEATURES.md +1410 -0
- package/temp/rtk/docs/TROUBLESHOOTING.md +309 -0
- package/temp/rtk/docs/filter-workflow.md +102 -0
- package/temp/rtk/docs/images/gain-dashboard.jpg +0 -0
- package/temp/rtk/docs/tracking.md +583 -0
- package/temp/rtk/hooks/opencode-rtk.ts +39 -0
- package/temp/rtk/hooks/rtk-awareness.md +29 -0
- package/temp/rtk/hooks/rtk-rewrite.sh +61 -0
- package/temp/rtk/hooks/test-rtk-rewrite.sh +442 -0
- package/temp/rtk/install.sh +124 -0
- package/temp/rtk/release-please-config.json +10 -0
- package/temp/rtk/scripts/benchmark.sh +592 -0
- package/temp/rtk/scripts/check-installation.sh +162 -0
- package/temp/rtk/scripts/install-local.sh +37 -0
- package/temp/rtk/scripts/rtk-economics.sh +137 -0
- package/temp/rtk/scripts/test-all.sh +561 -0
- package/temp/rtk/scripts/test-aristote.sh +227 -0
- package/temp/rtk/scripts/test-tracking.sh +79 -0
- package/temp/rtk/scripts/update-readme-metrics.sh +32 -0
- package/temp/rtk/scripts/validate-docs.sh +73 -0
- package/temp/rtk/src/aws_cmd.rs +880 -0
- package/temp/rtk/src/binlog.rs +1645 -0
- package/temp/rtk/src/cargo_cmd.rs +1727 -0
- package/temp/rtk/src/cc_economics.rs +1157 -0
- package/temp/rtk/src/ccusage.rs +340 -0
- package/temp/rtk/src/config.rs +187 -0
- package/temp/rtk/src/container.rs +855 -0
- package/temp/rtk/src/curl_cmd.rs +134 -0
- package/temp/rtk/src/deps.rs +268 -0
- package/temp/rtk/src/diff_cmd.rs +367 -0
- package/temp/rtk/src/discover/mod.rs +274 -0
- package/temp/rtk/src/discover/provider.rs +388 -0
- package/temp/rtk/src/discover/registry.rs +2022 -0
- package/temp/rtk/src/discover/report.rs +202 -0
- package/temp/rtk/src/discover/rules.rs +667 -0
- package/temp/rtk/src/display_helpers.rs +402 -0
- package/temp/rtk/src/dotnet_cmd.rs +1771 -0
- package/temp/rtk/src/dotnet_format_report.rs +133 -0
- package/temp/rtk/src/dotnet_trx.rs +593 -0
- package/temp/rtk/src/env_cmd.rs +204 -0
- package/temp/rtk/src/filter.rs +462 -0
- package/temp/rtk/src/filters/README.md +52 -0
- package/temp/rtk/src/filters/ansible-playbook.toml +34 -0
- package/temp/rtk/src/filters/basedpyright.toml +47 -0
- package/temp/rtk/src/filters/biome.toml +45 -0
- package/temp/rtk/src/filters/brew-install.toml +37 -0
- package/temp/rtk/src/filters/composer-install.toml +40 -0
- package/temp/rtk/src/filters/df.toml +16 -0
- package/temp/rtk/src/filters/dotnet-build.toml +64 -0
- package/temp/rtk/src/filters/du.toml +16 -0
- package/temp/rtk/src/filters/fail2ban-client.toml +15 -0
- package/temp/rtk/src/filters/gcc.toml +49 -0
- package/temp/rtk/src/filters/gcloud.toml +22 -0
- package/temp/rtk/src/filters/hadolint.toml +24 -0
- package/temp/rtk/src/filters/helm.toml +29 -0
- package/temp/rtk/src/filters/iptables.toml +27 -0
- package/temp/rtk/src/filters/jj.toml +28 -0
- package/temp/rtk/src/filters/jq.toml +24 -0
- package/temp/rtk/src/filters/make.toml +41 -0
- package/temp/rtk/src/filters/markdownlint.toml +24 -0
- package/temp/rtk/src/filters/mix-compile.toml +27 -0
- package/temp/rtk/src/filters/mix-format.toml +15 -0
- package/temp/rtk/src/filters/mvn-build.toml +44 -0
- package/temp/rtk/src/filters/oxlint.toml +43 -0
- package/temp/rtk/src/filters/ping.toml +63 -0
- package/temp/rtk/src/filters/pio-run.toml +40 -0
- package/temp/rtk/src/filters/poetry-install.toml +50 -0
- package/temp/rtk/src/filters/pre-commit.toml +35 -0
- package/temp/rtk/src/filters/ps.toml +16 -0
- package/temp/rtk/src/filters/quarto-render.toml +41 -0
- package/temp/rtk/src/filters/rsync.toml +48 -0
- package/temp/rtk/src/filters/shellcheck.toml +27 -0
- package/temp/rtk/src/filters/shopify-theme.toml +29 -0
- package/temp/rtk/src/filters/skopeo.toml +45 -0
- package/temp/rtk/src/filters/sops.toml +16 -0
- package/temp/rtk/src/filters/ssh.toml +44 -0
- package/temp/rtk/src/filters/stat.toml +34 -0
- package/temp/rtk/src/filters/swift-build.toml +41 -0
- package/temp/rtk/src/filters/systemctl-status.toml +33 -0
- package/temp/rtk/src/filters/terraform-plan.toml +35 -0
- package/temp/rtk/src/filters/tofu-fmt.toml +16 -0
- package/temp/rtk/src/filters/tofu-init.toml +38 -0
- package/temp/rtk/src/filters/tofu-plan.toml +35 -0
- package/temp/rtk/src/filters/tofu-validate.toml +17 -0
- package/temp/rtk/src/filters/trunk-build.toml +39 -0
- package/temp/rtk/src/filters/ty.toml +50 -0
- package/temp/rtk/src/filters/uv-sync.toml +37 -0
- package/temp/rtk/src/filters/xcodebuild.toml +99 -0
- package/temp/rtk/src/filters/yamllint.toml +25 -0
- package/temp/rtk/src/find_cmd.rs +598 -0
- package/temp/rtk/src/format_cmd.rs +386 -0
- package/temp/rtk/src/gain.rs +723 -0
- package/temp/rtk/src/gh_cmd.rs +1651 -0
- package/temp/rtk/src/git.rs +2012 -0
- package/temp/rtk/src/go_cmd.rs +592 -0
- package/temp/rtk/src/golangci_cmd.rs +254 -0
- package/temp/rtk/src/grep_cmd.rs +288 -0
- package/temp/rtk/src/gt_cmd.rs +810 -0
- package/temp/rtk/src/hook_audit_cmd.rs +283 -0
- package/temp/rtk/src/hook_check.rs +171 -0
- package/temp/rtk/src/init.rs +1859 -0
- package/temp/rtk/src/integrity.rs +537 -0
- package/temp/rtk/src/json_cmd.rs +231 -0
- package/temp/rtk/src/learn/detector.rs +628 -0
- package/temp/rtk/src/learn/mod.rs +119 -0
- package/temp/rtk/src/learn/report.rs +184 -0
- package/temp/rtk/src/lint_cmd.rs +694 -0
- package/temp/rtk/src/local_llm.rs +316 -0
- package/temp/rtk/src/log_cmd.rs +248 -0
- package/temp/rtk/src/ls.rs +324 -0
- package/temp/rtk/src/main.rs +2482 -0
- package/temp/rtk/src/mypy_cmd.rs +389 -0
- package/temp/rtk/src/next_cmd.rs +241 -0
- package/temp/rtk/src/npm_cmd.rs +236 -0
- package/temp/rtk/src/parser/README.md +267 -0
- package/temp/rtk/src/parser/error.rs +46 -0
- package/temp/rtk/src/parser/formatter.rs +336 -0
- package/temp/rtk/src/parser/mod.rs +311 -0
- package/temp/rtk/src/parser/types.rs +119 -0
- package/temp/rtk/src/pip_cmd.rs +302 -0
- package/temp/rtk/src/playwright_cmd.rs +479 -0
- package/temp/rtk/src/pnpm_cmd.rs +573 -0
- package/temp/rtk/src/prettier_cmd.rs +221 -0
- package/temp/rtk/src/prisma_cmd.rs +482 -0
- package/temp/rtk/src/psql_cmd.rs +382 -0
- package/temp/rtk/src/pytest_cmd.rs +384 -0
- package/temp/rtk/src/read.rs +217 -0
- package/temp/rtk/src/rewrite_cmd.rs +50 -0
- package/temp/rtk/src/ruff_cmd.rs +402 -0
- package/temp/rtk/src/runner.rs +271 -0
- package/temp/rtk/src/summary.rs +297 -0
- package/temp/rtk/src/tee.rs +405 -0
- package/temp/rtk/src/telemetry.rs +248 -0
- package/temp/rtk/src/toml_filter.rs +1655 -0
- package/temp/rtk/src/tracking.rs +1416 -0
- package/temp/rtk/src/tree.rs +209 -0
- package/temp/rtk/src/tsc_cmd.rs +259 -0
- package/temp/rtk/src/utils.rs +432 -0
- package/temp/rtk/src/verify_cmd.rs +47 -0
- package/temp/rtk/src/vitest_cmd.rs +385 -0
- package/temp/rtk/src/wc_cmd.rs +401 -0
- package/temp/rtk/src/wget_cmd.rs +260 -0
- package/temp/rtk/tests/fixtures/dotnet/build_failed.txt +11 -0
- package/temp/rtk/tests/fixtures/dotnet/format_changes.json +31 -0
- package/temp/rtk/tests/fixtures/dotnet/format_empty.json +1 -0
- package/temp/rtk/tests/fixtures/dotnet/format_success.json +12 -0
- package/temp/rtk/tests/fixtures/dotnet/test_failed.txt +18 -0
- package/dist/App.js +0 -404
- package/dist/Browse.js +0 -79
- package/dist/FuzzyPicker.js +0 -47
- package/dist/Onboarding.js +0 -51
- package/dist/Spinner.js +0 -12
- package/dist/StatusBar.js +0 -49
- package/dist/ai.js +0 -368
- package/dist/cache.js +0 -41
- package/dist/command-rewriter.js +0 -64
- package/dist/command-validator.js +0 -77
- package/dist/compression.js +0 -107
- package/dist/diff-cache.js +0 -107
- package/dist/economy.js +0 -79
- package/dist/expand-store.js +0 -38
- package/dist/file-cache.js +0 -72
- package/dist/file-index.js +0 -62
- package/dist/history.js +0 -62
- package/dist/lazy-executor.js +0 -54
- package/dist/line-dedup.js +0 -59
- package/dist/loop-detector.js +0 -75
- package/dist/mcp/install.js +0 -98
- package/dist/mcp/server.js +0 -569
- package/dist/noise-filter.js +0 -86
- package/dist/output-processor.js +0 -136
- package/dist/output-router.js +0 -41
- package/dist/parsers/base.js +0 -2
- package/dist/parsers/build.js +0 -64
- package/dist/parsers/errors.js +0 -101
- package/dist/parsers/files.js +0 -78
- package/dist/parsers/git.js +0 -99
- package/dist/parsers/index.js +0 -48
- package/dist/parsers/tests.js +0 -89
- package/dist/providers/anthropic.js +0 -39
- package/dist/providers/base.js +0 -4
- package/dist/providers/cerebras.js +0 -95
- package/dist/providers/index.js +0 -49
- package/dist/recipes/model.js +0 -20
- package/dist/recipes/storage.js +0 -136
- package/dist/search/content-search.js +0 -68
- package/dist/search/file-search.js +0 -61
- package/dist/search/filters.js +0 -34
- package/dist/search/index.js +0 -5
- package/dist/search/semantic.js +0 -320
- package/dist/session-boot.js +0 -59
- package/dist/session-context.js +0 -55
- package/dist/sessions-db.js +0 -120
- package/dist/smart-display.js +0 -286
- package/dist/snapshots.js +0 -51
- package/dist/supervisor.js +0 -112
- package/dist/test-watchlist.js +0 -131
- package/dist/tree.js +0 -94
- package/dist/usage-cache.js +0 -65
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rtk-testing-specialist
|
|
3
|
+
description: RTK testing expert - snapshot tests, token accuracy, cross-platform validation
|
|
4
|
+
model: sonnet
|
|
5
|
+
tools: Read, Write, Edit, Bash, Grep, Glob
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# RTK Testing Specialist
|
|
9
|
+
|
|
10
|
+
You are a testing expert specializing in RTK's unique testing needs: command output validation, token counting accuracy, and cross-platform shell compatibility.
|
|
11
|
+
|
|
12
|
+
## Core Responsibilities
|
|
13
|
+
|
|
14
|
+
- **Snapshot testing**: Use `insta` crate for output validation
|
|
15
|
+
- **Token accuracy**: Verify 60-90% savings claims with real fixtures
|
|
16
|
+
- **Cross-platform**: Test bash/zsh/PowerShell compatibility
|
|
17
|
+
- **Regression prevention**: Detect performance degradation in CI
|
|
18
|
+
- **Integration tests**: Real command execution (git, cargo, gh, pnpm, etc.)
|
|
19
|
+
|
|
20
|
+
## Testing Patterns
|
|
21
|
+
|
|
22
|
+
### Snapshot Testing with `insta`
|
|
23
|
+
|
|
24
|
+
RTK uses the `insta` crate for snapshot-based output validation. This is the **primary testing strategy** for filters.
|
|
25
|
+
|
|
26
|
+
```rust
|
|
27
|
+
use insta::assert_snapshot;
|
|
28
|
+
|
|
29
|
+
#[test]
|
|
30
|
+
fn test_git_log_output() {
|
|
31
|
+
let input = include_str!("../tests/fixtures/git_log_raw.txt");
|
|
32
|
+
let output = filter_git_log(input);
|
|
33
|
+
|
|
34
|
+
// Snapshot test - will fail if output changes
|
|
35
|
+
// First run: creates snapshot
|
|
36
|
+
// Subsequent runs: compares against snapshot
|
|
37
|
+
assert_snapshot!(output);
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Workflow**:
|
|
42
|
+
1. **Write test**: Add `assert_snapshot!(output);` in test
|
|
43
|
+
2. **Run tests**: `cargo test` (will create new snapshots)
|
|
44
|
+
3. **Review snapshots**: `cargo insta review` (interactive review)
|
|
45
|
+
4. **Accept changes**: `cargo insta accept` (if output is correct)
|
|
46
|
+
|
|
47
|
+
**When to use**:
|
|
48
|
+
- **All new filters**: Every filter should have at least one snapshot test
|
|
49
|
+
- **Output format changes**: When modifying filter logic
|
|
50
|
+
- **Regression detection**: Catch unintended output changes
|
|
51
|
+
|
|
52
|
+
**Example workflow** (adding snapshot test):
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# 1. Create fixture
|
|
56
|
+
echo "raw command output" > tests/fixtures/newcmd_raw.txt
|
|
57
|
+
|
|
58
|
+
# 2. Write test
|
|
59
|
+
cat > src/newcmd_cmd.rs <<'EOF'
|
|
60
|
+
#[cfg(test)]
|
|
61
|
+
mod tests {
|
|
62
|
+
use super::*;
|
|
63
|
+
use insta::assert_snapshot;
|
|
64
|
+
|
|
65
|
+
#[test]
|
|
66
|
+
fn test_newcmd_output_format() {
|
|
67
|
+
let input = include_str!("../tests/fixtures/newcmd_raw.txt");
|
|
68
|
+
let output = filter_newcmd(input);
|
|
69
|
+
assert_snapshot!(output);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
EOF
|
|
73
|
+
|
|
74
|
+
# 3. Run test (creates snapshot)
|
|
75
|
+
cargo test test_newcmd_output_format
|
|
76
|
+
|
|
77
|
+
# 4. Review snapshot
|
|
78
|
+
cargo insta review
|
|
79
|
+
# Press 'a' to accept, 'r' to reject
|
|
80
|
+
|
|
81
|
+
# 5. Snapshot saved in snapshots/
|
|
82
|
+
ls -la src/snapshots/
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Token Count Validation
|
|
86
|
+
|
|
87
|
+
All filters **MUST** verify token savings claims (60-90%) in tests:
|
|
88
|
+
|
|
89
|
+
```rust
|
|
90
|
+
#[cfg(test)]
|
|
91
|
+
mod tests {
|
|
92
|
+
use super::*;
|
|
93
|
+
|
|
94
|
+
// Helper function (add to tests/common/mod.rs if not exists)
|
|
95
|
+
fn count_tokens(text: &str) -> usize {
|
|
96
|
+
// Simple whitespace tokenization (good enough for tests)
|
|
97
|
+
text.split_whitespace().count()
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
#[test]
|
|
101
|
+
fn test_token_savings_claim() {
|
|
102
|
+
let fixtures = [
|
|
103
|
+
("git_log", 0.80), // 80% savings expected
|
|
104
|
+
("cargo_test", 0.90), // 90% savings expected
|
|
105
|
+
("gh_pr_view", 0.87), // 87% savings expected
|
|
106
|
+
];
|
|
107
|
+
|
|
108
|
+
for (name, expected_savings) in fixtures {
|
|
109
|
+
let input = include_str!(&format!("../tests/fixtures/{}_raw.txt", name));
|
|
110
|
+
let output = apply_filter(name, input);
|
|
111
|
+
|
|
112
|
+
let input_tokens = count_tokens(input);
|
|
113
|
+
let output_tokens = count_tokens(&output);
|
|
114
|
+
|
|
115
|
+
let savings = 100.0 - (output_tokens as f64 / input_tokens as f64 * 100.0);
|
|
116
|
+
|
|
117
|
+
assert!(
|
|
118
|
+
savings >= expected_savings,
|
|
119
|
+
"{} filter: expected ≥{:.0}% savings, got {:.1}%",
|
|
120
|
+
name, expected_savings * 100.0, savings * 100.0
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Why critical**: RTK promises 60-90% token savings. Tests must verify these claims with real fixtures. If savings drop below 60%, it's a **release blocker**.
|
|
128
|
+
|
|
129
|
+
**Creating fixtures**:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# Capture real command output
|
|
133
|
+
git log -20 > tests/fixtures/git_log_raw.txt
|
|
134
|
+
cargo test > tests/fixtures/cargo_test_raw.txt 2>&1
|
|
135
|
+
gh pr view 123 > tests/fixtures/gh_pr_view_raw.txt
|
|
136
|
+
|
|
137
|
+
# Then test with:
|
|
138
|
+
# let input = include_str!("../tests/fixtures/git_log_raw.txt");
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Cross-Platform Shell Escaping
|
|
142
|
+
|
|
143
|
+
RTK must work on macOS (zsh), Linux (bash), Windows (PowerShell). Shell escaping differs:
|
|
144
|
+
|
|
145
|
+
```rust
|
|
146
|
+
#[cfg(target_os = "windows")]
|
|
147
|
+
const EXPECTED_SHELL: &str = "cmd.exe";
|
|
148
|
+
|
|
149
|
+
#[cfg(target_os = "macos")]
|
|
150
|
+
const EXPECTED_SHELL: &str = "zsh";
|
|
151
|
+
|
|
152
|
+
#[cfg(target_os = "linux")]
|
|
153
|
+
const EXPECTED_SHELL: &str = "bash";
|
|
154
|
+
|
|
155
|
+
#[test]
|
|
156
|
+
fn test_shell_escaping() {
|
|
157
|
+
let cmd = r#"git log --format="%H %s""#;
|
|
158
|
+
let escaped = escape_for_shell(cmd);
|
|
159
|
+
|
|
160
|
+
#[cfg(target_os = "windows")]
|
|
161
|
+
assert_eq!(escaped, r#"git log --format=\"%H %s\""#);
|
|
162
|
+
|
|
163
|
+
#[cfg(not(target_os = "windows"))]
|
|
164
|
+
assert_eq!(escaped, r#"git log --format="%H %s""#);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
#[test]
|
|
168
|
+
fn test_command_execution_cross_platform() {
|
|
169
|
+
let result = execute_command("git", &["--version"]);
|
|
170
|
+
assert!(result.is_ok());
|
|
171
|
+
|
|
172
|
+
let output = result.unwrap();
|
|
173
|
+
assert!(output.contains("git version"));
|
|
174
|
+
|
|
175
|
+
// Verify exit code preserved
|
|
176
|
+
assert_eq!(output.status, 0);
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**Testing platforms**:
|
|
181
|
+
- **macOS**: `cargo test` (local)
|
|
182
|
+
- **Linux**: `docker run --rm -v $(pwd):/rtk -w /rtk rust:latest cargo test`
|
|
183
|
+
- **Windows**: Trust CI/CD or test manually if available
|
|
184
|
+
|
|
185
|
+
### Integration Tests (Real Commands)
|
|
186
|
+
|
|
187
|
+
Integration tests execute real commands via RTK to verify end-to-end behavior:
|
|
188
|
+
|
|
189
|
+
```rust
|
|
190
|
+
#[test]
|
|
191
|
+
#[ignore] // Run with: cargo test --ignored
|
|
192
|
+
fn test_real_git_log() {
|
|
193
|
+
// Requires:
|
|
194
|
+
// 1. RTK binary installed (cargo install --path .)
|
|
195
|
+
// 2. Git repository available
|
|
196
|
+
|
|
197
|
+
let output = std::process::Command::new("rtk")
|
|
198
|
+
.args(&["git", "log", "-10"])
|
|
199
|
+
.output()
|
|
200
|
+
.expect("Failed to run rtk");
|
|
201
|
+
|
|
202
|
+
assert!(output.status.success(), "RTK exited with non-zero status");
|
|
203
|
+
assert!(!output.stdout.is_empty(), "RTK produced empty output");
|
|
204
|
+
|
|
205
|
+
// Verify condensed (not raw git output)
|
|
206
|
+
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
207
|
+
assert!(
|
|
208
|
+
stdout.len() < 5000,
|
|
209
|
+
"Output too large ({} bytes), filter not working",
|
|
210
|
+
stdout.len()
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
// Verify format preservation (spot check)
|
|
214
|
+
assert!(stdout.contains("commit") || stdout.contains("Author"));
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**Run integration tests**:
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
# Install RTK first
|
|
222
|
+
cargo install --path .
|
|
223
|
+
|
|
224
|
+
# Run integration tests
|
|
225
|
+
cargo test --ignored
|
|
226
|
+
|
|
227
|
+
# Specific integration test
|
|
228
|
+
cargo test --ignored test_real_git_log
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**When to write integration tests**:
|
|
232
|
+
- **New filter added**: Verify filter works with real command
|
|
233
|
+
- **Command routing changes**: Verify RTK intercepts correctly
|
|
234
|
+
- **Hook integration changes**: Verify Claude Code hook rewriting works
|
|
235
|
+
|
|
236
|
+
## Test Coverage Strategy
|
|
237
|
+
|
|
238
|
+
**Priority targets**:
|
|
239
|
+
1. 🔴 **All filters**: git, cargo, gh, pnpm, docker, lint, tsc, etc. → Snapshot + token accuracy
|
|
240
|
+
2. 🟡 **Edge cases**: Empty output, malformed input, unicode, ANSI codes
|
|
241
|
+
3. 🟢 **Performance**: Benchmark startup time (<10ms), memory usage (<5MB)
|
|
242
|
+
|
|
243
|
+
**Coverage goals**:
|
|
244
|
+
- **100% filter coverage**: Every filter has snapshot test + token accuracy test
|
|
245
|
+
- **95% token savings verification**: Fixtures with known savings (60-90%)
|
|
246
|
+
- **Cross-platform tests**: macOS + Linux (Windows in CI only)
|
|
247
|
+
|
|
248
|
+
**Coverage verification**:
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
# Install tarpaulin (code coverage tool)
|
|
252
|
+
cargo install cargo-tarpaulin
|
|
253
|
+
|
|
254
|
+
# Run coverage
|
|
255
|
+
cargo tarpaulin --out Html --output-dir coverage/
|
|
256
|
+
|
|
257
|
+
# Open coverage report
|
|
258
|
+
open coverage/index.html
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Commands
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
# Run all tests
|
|
265
|
+
cargo test --all
|
|
266
|
+
|
|
267
|
+
# Run snapshot tests only
|
|
268
|
+
cargo test --test snapshots
|
|
269
|
+
|
|
270
|
+
# Run integration tests (requires real commands + rtk installed)
|
|
271
|
+
cargo test --ignored
|
|
272
|
+
|
|
273
|
+
# Review snapshot changes
|
|
274
|
+
cargo insta review
|
|
275
|
+
|
|
276
|
+
# Accept all snapshot changes
|
|
277
|
+
cargo insta accept
|
|
278
|
+
|
|
279
|
+
# Benchmark performance
|
|
280
|
+
cargo bench
|
|
281
|
+
|
|
282
|
+
# Cross-platform testing (Linux via Docker)
|
|
283
|
+
docker run --rm -v $(pwd):/rtk -w /rtk rust:latest cargo test
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## Anti-Patterns
|
|
287
|
+
|
|
288
|
+
❌ **DON'T** test with hardcoded output → Use real command fixtures
|
|
289
|
+
- Create fixtures: `git log -20 > tests/fixtures/git_log_raw.txt`
|
|
290
|
+
- Then test: `include_str!("../tests/fixtures/git_log_raw.txt")`
|
|
291
|
+
|
|
292
|
+
❌ **DON'T** skip cross-platform tests → macOS ≠ Linux ≠ Windows
|
|
293
|
+
- Shell escaping differs
|
|
294
|
+
- Path separators differ
|
|
295
|
+
- Line endings differ
|
|
296
|
+
- Test on at least macOS + Linux
|
|
297
|
+
|
|
298
|
+
❌ **DON'T** ignore performance regressions → Benchmark in CI
|
|
299
|
+
- Startup time must be <10ms
|
|
300
|
+
- Memory usage must be <5MB
|
|
301
|
+
- Use `hyperfine` and `time -l` to verify
|
|
302
|
+
|
|
303
|
+
❌ **DON'T** accept <60% token savings → Fails promise to users
|
|
304
|
+
- All filters must achieve 60-90% savings
|
|
305
|
+
- Test with real fixtures, not synthetic data
|
|
306
|
+
- If savings drop, investigate and fix before merge
|
|
307
|
+
|
|
308
|
+
✅ **DO** use `insta` for snapshot tests
|
|
309
|
+
- Catches unintended output changes
|
|
310
|
+
- Easy to review and accept changes
|
|
311
|
+
- Standard tool for Rust output validation
|
|
312
|
+
|
|
313
|
+
✅ **DO** verify token savings with real fixtures
|
|
314
|
+
- Use real command output, not synthetic
|
|
315
|
+
- Calculate savings: `100.0 - (output_tokens / input_tokens * 100.0)`
|
|
316
|
+
- Assert `savings >= 60.0`
|
|
317
|
+
|
|
318
|
+
✅ **DO** test shell escaping on all platforms
|
|
319
|
+
- Use `#[cfg(target_os = "...")]` for platform-specific tests
|
|
320
|
+
- Test macOS, Linux, Windows (via CI)
|
|
321
|
+
|
|
322
|
+
✅ **DO** run integration tests before release
|
|
323
|
+
- Install RTK: `cargo install --path .`
|
|
324
|
+
- Run tests: `cargo test --ignored`
|
|
325
|
+
- Verify end-to-end behavior with real commands
|
|
326
|
+
|
|
327
|
+
## Testing Workflow (Step-by-Step)
|
|
328
|
+
|
|
329
|
+
### Adding Test for New Filter
|
|
330
|
+
|
|
331
|
+
**Scenario**: You just implemented `filter_newcmd()` in `src/newcmd_cmd.rs`.
|
|
332
|
+
|
|
333
|
+
**Steps**:
|
|
334
|
+
|
|
335
|
+
1. **Create fixture** (real command output):
|
|
336
|
+
```bash
|
|
337
|
+
newcmd --some-args > tests/fixtures/newcmd_raw.txt
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
2. **Add snapshot test** to `src/newcmd_cmd.rs`:
|
|
341
|
+
```rust
|
|
342
|
+
#[cfg(test)]
|
|
343
|
+
mod tests {
|
|
344
|
+
use super::*;
|
|
345
|
+
use insta::assert_snapshot;
|
|
346
|
+
|
|
347
|
+
#[test]
|
|
348
|
+
fn test_newcmd_output_format() {
|
|
349
|
+
let input = include_str!("../tests/fixtures/newcmd_raw.txt");
|
|
350
|
+
let output = filter_newcmd(input);
|
|
351
|
+
assert_snapshot!(output);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
3. **Run test** (creates snapshot):
|
|
357
|
+
```bash
|
|
358
|
+
cargo test test_newcmd_output_format
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
4. **Review snapshot**:
|
|
362
|
+
```bash
|
|
363
|
+
cargo insta review
|
|
364
|
+
# Press 'a' to accept if output looks correct
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
5. **Add token accuracy test**:
|
|
368
|
+
```rust
|
|
369
|
+
#[test]
|
|
370
|
+
fn test_newcmd_token_savings() {
|
|
371
|
+
let input = include_str!("../tests/fixtures/newcmd_raw.txt");
|
|
372
|
+
let output = filter_newcmd(input);
|
|
373
|
+
|
|
374
|
+
let input_tokens = count_tokens(input);
|
|
375
|
+
let output_tokens = count_tokens(&output);
|
|
376
|
+
let savings = 100.0 - (output_tokens as f64 / input_tokens as f64 * 100.0);
|
|
377
|
+
|
|
378
|
+
assert!(savings >= 60.0, "Expected ≥60% savings, got {:.1}%", savings);
|
|
379
|
+
}
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
6. **Run all tests**:
|
|
383
|
+
```bash
|
|
384
|
+
cargo test --all
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
7. **Commit**:
|
|
388
|
+
```bash
|
|
389
|
+
git add src/newcmd_cmd.rs tests/fixtures/newcmd_raw.txt src/snapshots/
|
|
390
|
+
git commit -m "test(newcmd): add snapshot + token accuracy tests"
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
### Updating Filter (with Snapshot Test)
|
|
394
|
+
|
|
395
|
+
**Scenario**: You modified `filter_git_log()` output format.
|
|
396
|
+
|
|
397
|
+
**Steps**:
|
|
398
|
+
|
|
399
|
+
1. **Run tests** (will fail - snapshot mismatch):
|
|
400
|
+
```bash
|
|
401
|
+
cargo test test_git_log_output_format
|
|
402
|
+
# Output: snapshot mismatch detected
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
2. **Review changes**:
|
|
406
|
+
```bash
|
|
407
|
+
cargo insta review
|
|
408
|
+
# Shows diff: old vs new snapshot
|
|
409
|
+
# Press 'a' to accept if intentional
|
|
410
|
+
# Press 'r' to reject if bug
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
3. **If rejected**: Fix filter logic, re-run tests
|
|
414
|
+
|
|
415
|
+
4. **If accepted**: Snapshot updated, commit:
|
|
416
|
+
```bash
|
|
417
|
+
git add src/snapshots/
|
|
418
|
+
git commit -m "refactor(git): update log output format"
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
### Running Integration Tests
|
|
422
|
+
|
|
423
|
+
**Before release** (or when modifying critical paths):
|
|
424
|
+
|
|
425
|
+
```bash
|
|
426
|
+
# 1. Install RTK locally
|
|
427
|
+
cargo install --path . --force
|
|
428
|
+
|
|
429
|
+
# 2. Run integration tests
|
|
430
|
+
cargo test --ignored
|
|
431
|
+
|
|
432
|
+
# 3. Verify output
|
|
433
|
+
# All tests should pass
|
|
434
|
+
# If failures: investigate and fix before release
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
## Test Organization
|
|
438
|
+
|
|
439
|
+
```
|
|
440
|
+
rtk/
|
|
441
|
+
├── src/
|
|
442
|
+
│ ├── git.rs # Filter implementation
|
|
443
|
+
│ │ └── #[cfg(test)] mod tests { ... } # Unit tests
|
|
444
|
+
│ ├── snapshots/ # Insta snapshots (gitignored pattern)
|
|
445
|
+
│ │ └── git.rs.snap # Snapshot for git tests
|
|
446
|
+
├── tests/
|
|
447
|
+
│ ├── common/
|
|
448
|
+
│ │ └── mod.rs # Shared test utilities (count_tokens, etc.)
|
|
449
|
+
│ ├── fixtures/ # Real command output fixtures
|
|
450
|
+
│ │ ├── git_log_raw.txt # Real git log output
|
|
451
|
+
│ │ ├── cargo_test_raw.txt # Real cargo test output
|
|
452
|
+
│ │ └── gh_pr_view_raw.txt # Real gh pr view output
|
|
453
|
+
│ └── integration_test.rs # Integration tests (#[ignore])
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
**Best practices**:
|
|
457
|
+
- Unit tests: Embedded in module (`#[cfg(test)] mod tests`)
|
|
458
|
+
- Fixtures: In `tests/fixtures/` (real command output)
|
|
459
|
+
- Snapshots: In `src/snapshots/` (auto-generated by insta)
|
|
460
|
+
- Shared utils: In `tests/common/mod.rs` (count_tokens, helpers)
|
|
461
|
+
- Integration: In `tests/` with `#[ignore]` attribute
|