autonomous-coding-toolkit 1.0.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/.claude-plugin/marketplace.json +22 -0
- package/.claude-plugin/plugin.json +13 -0
- package/LICENSE +21 -0
- package/Makefile +21 -0
- package/README.md +140 -0
- package/SECURITY.md +28 -0
- package/agents/bash-expert.md +113 -0
- package/agents/dependency-auditor.md +138 -0
- package/agents/integration-tester.md +120 -0
- package/agents/lesson-scanner.md +149 -0
- package/agents/python-expert.md +179 -0
- package/agents/service-monitor.md +141 -0
- package/agents/shell-expert.md +147 -0
- package/benchmarks/runner.sh +147 -0
- package/benchmarks/tasks/01-rest-endpoint/rubric.sh +29 -0
- package/benchmarks/tasks/01-rest-endpoint/task.md +17 -0
- package/benchmarks/tasks/02-refactor-module/task.md +8 -0
- package/benchmarks/tasks/03-fix-integration-bug/task.md +8 -0
- package/benchmarks/tasks/04-add-test-coverage/task.md +8 -0
- package/benchmarks/tasks/05-multi-file-feature/task.md +8 -0
- package/bin/act.js +238 -0
- package/commands/autocode.md +6 -0
- package/commands/cancel-ralph.md +18 -0
- package/commands/code-factory.md +53 -0
- package/commands/create-prd.md +55 -0
- package/commands/ralph-loop.md +18 -0
- package/commands/run-plan.md +117 -0
- package/commands/submit-lesson.md +122 -0
- package/docs/ARCHITECTURE.md +630 -0
- package/docs/CONTRIBUTING.md +125 -0
- package/docs/lessons/0001-bare-exception-swallowing.md +34 -0
- package/docs/lessons/0002-async-def-without-await.md +28 -0
- package/docs/lessons/0003-create-task-without-callback.md +28 -0
- package/docs/lessons/0004-hardcoded-test-counts.md +28 -0
- package/docs/lessons/0005-sqlite-without-closing.md +33 -0
- package/docs/lessons/0006-venv-pip-path.md +27 -0
- package/docs/lessons/0007-runner-state-self-rejection.md +35 -0
- package/docs/lessons/0008-quality-gate-blind-spot.md +33 -0
- package/docs/lessons/0009-parser-overcount-empty-batches.md +36 -0
- package/docs/lessons/0010-local-outside-function-bash.md +33 -0
- package/docs/lessons/0011-batch-tests-for-unimplemented-code.md +36 -0
- package/docs/lessons/0012-api-markdown-unescaped-chars.md +33 -0
- package/docs/lessons/0013-export-prefix-env-parsing.md +33 -0
- package/docs/lessons/0014-decorator-registry-import-side-effect.md +43 -0
- package/docs/lessons/0015-frontend-backend-schema-drift.md +43 -0
- package/docs/lessons/0016-event-driven-cold-start-seeding.md +44 -0
- package/docs/lessons/0017-copy-paste-logic-diverges.md +43 -0
- package/docs/lessons/0018-layer-passes-pipeline-broken.md +45 -0
- package/docs/lessons/0019-systemd-envfile-ignores-export.md +41 -0
- package/docs/lessons/0020-persist-state-incrementally.md +44 -0
- package/docs/lessons/0021-dual-axis-testing.md +48 -0
- package/docs/lessons/0022-jsx-factory-shadowing.md +43 -0
- package/docs/lessons/0023-static-analysis-spiral.md +51 -0
- package/docs/lessons/0024-shared-pipeline-implementation.md +55 -0
- package/docs/lessons/0025-defense-in-depth-all-entry-points.md +65 -0
- package/docs/lessons/0026-linter-no-rules-false-enforcement.md +54 -0
- package/docs/lessons/0027-jsx-silent-prop-drop.md +64 -0
- package/docs/lessons/0028-no-infrastructure-in-client-code.md +49 -0
- package/docs/lessons/0029-never-write-secrets-to-files.md +61 -0
- package/docs/lessons/0030-cache-merge-not-replace.md +62 -0
- package/docs/lessons/0031-verify-units-at-boundaries.md +66 -0
- package/docs/lessons/0032-module-lifecycle-subscribe-unsubscribe.md +89 -0
- package/docs/lessons/0033-async-iteration-mutable-snapshot.md +72 -0
- package/docs/lessons/0034-caller-missing-await-silent-discard.md +65 -0
- package/docs/lessons/0035-duplicate-registration-silent-overwrite.md +85 -0
- package/docs/lessons/0036-websocket-dirty-disconnect.md +33 -0
- package/docs/lessons/0037-parallel-agents-worktree-corruption.md +31 -0
- package/docs/lessons/0038-subscribe-no-stored-ref.md +36 -0
- package/docs/lessons/0039-fallback-or-default-hides-bugs.md +34 -0
- package/docs/lessons/0040-event-firehose-filter-first.md +36 -0
- package/docs/lessons/0041-ambiguous-base-dir-path-nesting.md +32 -0
- package/docs/lessons/0042-spec-compliance-insufficient.md +36 -0
- package/docs/lessons/0043-exact-count-extensible-collections.md +32 -0
- package/docs/lessons/0044-relative-file-deps-worktree.md +39 -0
- package/docs/lessons/0045-iterative-design-improvement.md +33 -0
- package/docs/lessons/0046-plan-assertion-math-bugs.md +38 -0
- package/docs/lessons/0047-pytest-single-threaded-default.md +37 -0
- package/docs/lessons/0048-integration-wiring-batch.md +40 -0
- package/docs/lessons/0049-ab-verification.md +41 -0
- package/docs/lessons/0050-editing-sourced-files-during-execution.md +33 -0
- package/docs/lessons/0051-infrastructure-fixes-cant-self-heal.md +30 -0
- package/docs/lessons/0052-uncommitted-changes-poison-quality-gates.md +31 -0
- package/docs/lessons/0053-jq-compact-flag-inconsistency.md +31 -0
- package/docs/lessons/0054-parser-matches-inside-code-blocks.md +30 -0
- package/docs/lessons/0055-agents-compensate-for-garbled-prompts.md +31 -0
- package/docs/lessons/0056-grep-count-exit-code-on-zero.md +42 -0
- package/docs/lessons/0057-new-artifacts-break-git-clean-gates.md +42 -0
- package/docs/lessons/0058-dead-config-keys-never-consumed.md +49 -0
- package/docs/lessons/0059-contract-test-shared-structures.md +53 -0
- package/docs/lessons/0060-set-e-silent-death-in-runners.md +53 -0
- package/docs/lessons/0061-context-injection-dirty-state.md +50 -0
- package/docs/lessons/0062-sibling-bug-neighborhood-scan.md +29 -0
- package/docs/lessons/0063-one-flag-two-lifetimes.md +31 -0
- package/docs/lessons/0064-test-passes-wrong-reason.md +31 -0
- package/docs/lessons/0065-pipefail-grep-count-double-output.md +39 -0
- package/docs/lessons/0066-local-keyword-outside-function.md +37 -0
- package/docs/lessons/0067-stdin-hang-non-interactive-shell.md +36 -0
- package/docs/lessons/0068-agent-builds-wrong-thing-correctly.md +31 -0
- package/docs/lessons/0069-plan-quality-dominates-execution.md +30 -0
- package/docs/lessons/0070-spec-echo-back-prevents-drift.md +31 -0
- package/docs/lessons/0071-positive-instructions-outperform-negative.md +30 -0
- package/docs/lessons/0072-lost-in-the-middle-context-placement.md +30 -0
- package/docs/lessons/0073-unscoped-lessons-cause-false-positives.md +30 -0
- package/docs/lessons/0074-stale-context-injection-wrong-batch.md +32 -0
- package/docs/lessons/0075-research-artifacts-must-persist.md +32 -0
- package/docs/lessons/0076-wrong-decomposition-contaminates-downstream.md +30 -0
- package/docs/lessons/0077-cherry-pick-merges-need-manual-resolution.md +30 -0
- package/docs/lessons/0078-static-review-without-live-test.md +30 -0
- package/docs/lessons/0079-integration-wiring-batch-required.md +32 -0
- package/docs/lessons/FRAMEWORK.md +161 -0
- package/docs/lessons/SUMMARY.md +201 -0
- package/docs/lessons/TEMPLATE.md +85 -0
- package/docs/plans/2026-02-21-code-factory-v2-design.md +204 -0
- package/docs/plans/2026-02-21-code-factory-v2-implementation-plan.md +2189 -0
- package/docs/plans/2026-02-21-code-factory-v2-phase4-design.md +537 -0
- package/docs/plans/2026-02-21-code-factory-v2-phase4-implementation-plan.md +2012 -0
- package/docs/plans/2026-02-21-hardening-pass-design.md +108 -0
- package/docs/plans/2026-02-21-hardening-pass-plan.md +1378 -0
- package/docs/plans/2026-02-21-mab-research-report.md +406 -0
- package/docs/plans/2026-02-21-marketplace-restructure-design.md +240 -0
- package/docs/plans/2026-02-21-marketplace-restructure-plan.md +832 -0
- package/docs/plans/2026-02-21-phase4-completion-plan.md +697 -0
- package/docs/plans/2026-02-21-validator-suite-design.md +148 -0
- package/docs/plans/2026-02-21-validator-suite-plan.md +540 -0
- package/docs/plans/2026-02-22-mab-research-round2.md +556 -0
- package/docs/plans/2026-02-22-mab-run-design.md +462 -0
- package/docs/plans/2026-02-22-mab-run-plan.md +2046 -0
- package/docs/plans/2026-02-22-operations-design-methodology-research.md +681 -0
- package/docs/plans/2026-02-22-research-agent-failure-taxonomy.md +532 -0
- package/docs/plans/2026-02-22-research-code-guideline-policies.md +886 -0
- package/docs/plans/2026-02-22-research-codebase-audit-refactoring.md +908 -0
- package/docs/plans/2026-02-22-research-coding-standards-documentation.md +541 -0
- package/docs/plans/2026-02-22-research-competitive-landscape.md +687 -0
- package/docs/plans/2026-02-22-research-comprehensive-testing.md +1076 -0
- package/docs/plans/2026-02-22-research-context-utilization.md +459 -0
- package/docs/plans/2026-02-22-research-cost-quality-tradeoff.md +548 -0
- package/docs/plans/2026-02-22-research-lesson-transferability.md +508 -0
- package/docs/plans/2026-02-22-research-multi-agent-coordination.md +312 -0
- package/docs/plans/2026-02-22-research-phase-integration.md +602 -0
- package/docs/plans/2026-02-22-research-plan-quality.md +428 -0
- package/docs/plans/2026-02-22-research-prompt-engineering.md +558 -0
- package/docs/plans/2026-02-22-research-unconventional-perspectives.md +528 -0
- package/docs/plans/2026-02-22-research-user-adoption.md +638 -0
- package/docs/plans/2026-02-22-research-verification-effectiveness.md +433 -0
- package/docs/plans/2026-02-23-agent-suite-design.md +299 -0
- package/docs/plans/2026-02-23-agent-suite-plan.md +578 -0
- package/docs/plans/2026-02-23-phase3-cost-infrastructure-design.md +148 -0
- package/docs/plans/2026-02-23-phase3-cost-infrastructure-plan.md +1062 -0
- package/docs/plans/2026-02-23-research-bash-expert-agent.md +543 -0
- package/docs/plans/2026-02-23-research-dependency-auditor-agent.md +564 -0
- package/docs/plans/2026-02-23-research-improving-existing-agents.md +503 -0
- package/docs/plans/2026-02-23-research-integration-tester-agent.md +454 -0
- package/docs/plans/2026-02-23-research-python-expert-agent.md +429 -0
- package/docs/plans/2026-02-23-research-service-monitor-agent.md +425 -0
- package/docs/plans/2026-02-23-research-shell-expert-agent.md +533 -0
- package/docs/plans/2026-02-23-roadmap-to-completion.md +530 -0
- package/docs/plans/2026-02-24-headless-module-split-design.md +98 -0
- package/docs/plans/2026-02-24-headless-module-split.md +443 -0
- package/docs/plans/2026-02-24-lesson-scope-metadata-design.md +228 -0
- package/docs/plans/2026-02-24-lesson-scope-metadata-plan.md +968 -0
- package/docs/plans/2026-02-24-npm-packaging-design.md +841 -0
- package/docs/plans/2026-02-24-npm-packaging-plan.md +1965 -0
- package/docs/plans/audit-findings.md +186 -0
- package/docs/telegram-notification-format.md +98 -0
- package/examples/example-plan.md +51 -0
- package/examples/example-prd.json +72 -0
- package/examples/example-roadmap.md +33 -0
- package/examples/quickstart-plan.md +63 -0
- package/hooks/hooks.json +26 -0
- package/hooks/setup-symlinks.sh +48 -0
- package/hooks/stop-hook.sh +135 -0
- package/package.json +47 -0
- package/policies/bash.md +71 -0
- package/policies/python.md +71 -0
- package/policies/testing.md +61 -0
- package/policies/universal.md +60 -0
- package/scripts/analyze-report.sh +97 -0
- package/scripts/architecture-map.sh +145 -0
- package/scripts/auto-compound.sh +273 -0
- package/scripts/batch-audit.sh +42 -0
- package/scripts/batch-test.sh +101 -0
- package/scripts/entropy-audit.sh +221 -0
- package/scripts/failure-digest.sh +51 -0
- package/scripts/generate-ast-rules.sh +96 -0
- package/scripts/init.sh +112 -0
- package/scripts/lesson-check.sh +428 -0
- package/scripts/lib/common.sh +61 -0
- package/scripts/lib/cost-tracking.sh +153 -0
- package/scripts/lib/ollama.sh +60 -0
- package/scripts/lib/progress-writer.sh +128 -0
- package/scripts/lib/run-plan-context.sh +215 -0
- package/scripts/lib/run-plan-echo-back.sh +231 -0
- package/scripts/lib/run-plan-headless.sh +396 -0
- package/scripts/lib/run-plan-notify.sh +57 -0
- package/scripts/lib/run-plan-parser.sh +81 -0
- package/scripts/lib/run-plan-prompt.sh +215 -0
- package/scripts/lib/run-plan-quality-gate.sh +132 -0
- package/scripts/lib/run-plan-routing.sh +315 -0
- package/scripts/lib/run-plan-sampling.sh +170 -0
- package/scripts/lib/run-plan-scoring.sh +146 -0
- package/scripts/lib/run-plan-state.sh +142 -0
- package/scripts/lib/run-plan-team.sh +199 -0
- package/scripts/lib/telegram.sh +54 -0
- package/scripts/lib/thompson-sampling.sh +176 -0
- package/scripts/license-check.sh +74 -0
- package/scripts/mab-run.sh +575 -0
- package/scripts/module-size-check.sh +146 -0
- package/scripts/patterns/async-no-await.yml +5 -0
- package/scripts/patterns/bare-except.yml +6 -0
- package/scripts/patterns/empty-catch.yml +6 -0
- package/scripts/patterns/hardcoded-localhost.yml +9 -0
- package/scripts/patterns/retry-loop-no-backoff.yml +12 -0
- package/scripts/pipeline-status.sh +197 -0
- package/scripts/policy-check.sh +226 -0
- package/scripts/prior-art-search.sh +133 -0
- package/scripts/promote-mab-lessons.sh +126 -0
- package/scripts/prompts/agent-a-superpowers.md +29 -0
- package/scripts/prompts/agent-b-ralph.md +29 -0
- package/scripts/prompts/judge-agent.md +61 -0
- package/scripts/prompts/planner-agent.md +44 -0
- package/scripts/pull-community-lessons.sh +90 -0
- package/scripts/quality-gate.sh +266 -0
- package/scripts/research-gate.sh +90 -0
- package/scripts/run-plan.sh +329 -0
- package/scripts/scope-infer.sh +159 -0
- package/scripts/setup-ralph-loop.sh +155 -0
- package/scripts/telemetry.sh +230 -0
- package/scripts/tests/run-all-tests.sh +52 -0
- package/scripts/tests/test-act-cli.sh +46 -0
- package/scripts/tests/test-agents-md.sh +87 -0
- package/scripts/tests/test-analyze-report.sh +114 -0
- package/scripts/tests/test-architecture-map.sh +89 -0
- package/scripts/tests/test-auto-compound.sh +169 -0
- package/scripts/tests/test-batch-test.sh +65 -0
- package/scripts/tests/test-benchmark-runner.sh +25 -0
- package/scripts/tests/test-common.sh +168 -0
- package/scripts/tests/test-cost-tracking.sh +158 -0
- package/scripts/tests/test-echo-back.sh +180 -0
- package/scripts/tests/test-entropy-audit.sh +146 -0
- package/scripts/tests/test-failure-digest.sh +66 -0
- package/scripts/tests/test-generate-ast-rules.sh +145 -0
- package/scripts/tests/test-helpers.sh +82 -0
- package/scripts/tests/test-init.sh +47 -0
- package/scripts/tests/test-lesson-check.sh +278 -0
- package/scripts/tests/test-lesson-local.sh +55 -0
- package/scripts/tests/test-license-check.sh +109 -0
- package/scripts/tests/test-mab-run.sh +182 -0
- package/scripts/tests/test-ollama-lib.sh +49 -0
- package/scripts/tests/test-ollama.sh +60 -0
- package/scripts/tests/test-pipeline-status.sh +198 -0
- package/scripts/tests/test-policy-check.sh +124 -0
- package/scripts/tests/test-prior-art-search.sh +96 -0
- package/scripts/tests/test-progress-writer.sh +140 -0
- package/scripts/tests/test-promote-mab-lessons.sh +110 -0
- package/scripts/tests/test-pull-community-lessons.sh +149 -0
- package/scripts/tests/test-quality-gate.sh +241 -0
- package/scripts/tests/test-research-gate.sh +132 -0
- package/scripts/tests/test-run-plan-cli.sh +86 -0
- package/scripts/tests/test-run-plan-context.sh +305 -0
- package/scripts/tests/test-run-plan-e2e.sh +153 -0
- package/scripts/tests/test-run-plan-headless.sh +424 -0
- package/scripts/tests/test-run-plan-notify.sh +124 -0
- package/scripts/tests/test-run-plan-parser.sh +217 -0
- package/scripts/tests/test-run-plan-prompt.sh +254 -0
- package/scripts/tests/test-run-plan-quality-gate.sh +222 -0
- package/scripts/tests/test-run-plan-routing.sh +178 -0
- package/scripts/tests/test-run-plan-scoring.sh +148 -0
- package/scripts/tests/test-run-plan-state.sh +261 -0
- package/scripts/tests/test-run-plan-team.sh +157 -0
- package/scripts/tests/test-scope-infer.sh +150 -0
- package/scripts/tests/test-setup-ralph-loop.sh +63 -0
- package/scripts/tests/test-telegram-env.sh +38 -0
- package/scripts/tests/test-telegram.sh +121 -0
- package/scripts/tests/test-telemetry.sh +46 -0
- package/scripts/tests/test-thompson-sampling.sh +139 -0
- package/scripts/tests/test-validate-all.sh +60 -0
- package/scripts/tests/test-validate-commands.sh +89 -0
- package/scripts/tests/test-validate-hooks.sh +98 -0
- package/scripts/tests/test-validate-lessons.sh +150 -0
- package/scripts/tests/test-validate-plan-quality.sh +235 -0
- package/scripts/tests/test-validate-plans.sh +187 -0
- package/scripts/tests/test-validate-plugin.sh +106 -0
- package/scripts/tests/test-validate-prd.sh +184 -0
- package/scripts/tests/test-validate-skills.sh +134 -0
- package/scripts/validate-all.sh +57 -0
- package/scripts/validate-commands.sh +67 -0
- package/scripts/validate-hooks.sh +89 -0
- package/scripts/validate-lessons.sh +98 -0
- package/scripts/validate-plan-quality.sh +369 -0
- package/scripts/validate-plans.sh +120 -0
- package/scripts/validate-plugin.sh +86 -0
- package/scripts/validate-policies.sh +42 -0
- package/scripts/validate-prd.sh +118 -0
- package/scripts/validate-skills.sh +96 -0
- package/skills/autocode/SKILL.md +285 -0
- package/skills/autocode/ab-verification.md +51 -0
- package/skills/autocode/code-quality-standards.md +37 -0
- package/skills/autocode/competitive-mode.md +364 -0
- package/skills/brainstorming/SKILL.md +97 -0
- package/skills/capture-lesson/SKILL.md +187 -0
- package/skills/check-lessons/SKILL.md +116 -0
- package/skills/dispatching-parallel-agents/SKILL.md +110 -0
- package/skills/executing-plans/SKILL.md +85 -0
- package/skills/finishing-a-development-branch/SKILL.md +201 -0
- package/skills/receiving-code-review/SKILL.md +72 -0
- package/skills/requesting-code-review/SKILL.md +59 -0
- package/skills/requesting-code-review/code-reviewer.md +82 -0
- package/skills/research/SKILL.md +145 -0
- package/skills/roadmap/SKILL.md +115 -0
- package/skills/subagent-driven-development/SKILL.md +98 -0
- package/skills/subagent-driven-development/code-quality-reviewer-prompt.md +18 -0
- package/skills/subagent-driven-development/implementer-prompt.md +73 -0
- package/skills/subagent-driven-development/spec-reviewer-prompt.md +57 -0
- package/skills/systematic-debugging/SKILL.md +134 -0
- package/skills/systematic-debugging/condition-based-waiting.md +64 -0
- package/skills/systematic-debugging/defense-in-depth.md +32 -0
- package/skills/systematic-debugging/root-cause-tracing.md +55 -0
- package/skills/test-driven-development/SKILL.md +167 -0
- package/skills/using-git-worktrees/SKILL.md +219 -0
- package/skills/using-superpowers/SKILL.md +54 -0
- package/skills/verification-before-completion/SKILL.md +140 -0
- package/skills/verify/SKILL.md +82 -0
- package/skills/writing-plans/SKILL.md +128 -0
- package/skills/writing-skills/SKILL.md +93 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Test AGENTS.md generation
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
source "$SCRIPT_DIR/../lib/run-plan-parser.sh"
|
|
7
|
+
source "$SCRIPT_DIR/../lib/run-plan-prompt.sh"
|
|
8
|
+
|
|
9
|
+
FAILURES=0
|
|
10
|
+
TESTS=0
|
|
11
|
+
|
|
12
|
+
assert_eq() {
|
|
13
|
+
local desc="$1" expected="$2" actual="$3"
|
|
14
|
+
TESTS=$((TESTS + 1))
|
|
15
|
+
if [[ "$expected" != "$actual" ]]; then
|
|
16
|
+
echo "FAIL: $desc"
|
|
17
|
+
echo " expected: $expected"
|
|
18
|
+
echo " actual: $actual"
|
|
19
|
+
FAILURES=$((FAILURES + 1))
|
|
20
|
+
else
|
|
21
|
+
echo "PASS: $desc"
|
|
22
|
+
fi
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
assert_contains() {
|
|
26
|
+
local desc="$1" needle="$2" haystack="$3"
|
|
27
|
+
TESTS=$((TESTS + 1))
|
|
28
|
+
if echo "$haystack" | grep -qF "$needle"; then
|
|
29
|
+
echo "PASS: $desc"
|
|
30
|
+
else
|
|
31
|
+
echo "FAIL: $desc"
|
|
32
|
+
echo " expected to contain: $needle"
|
|
33
|
+
FAILURES=$((FAILURES + 1))
|
|
34
|
+
fi
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
WORK=$(mktemp -d)
|
|
38
|
+
trap 'rm -rf "$WORK"' EXIT
|
|
39
|
+
|
|
40
|
+
# Create a test plan
|
|
41
|
+
cat > "$WORK/plan.md" << 'PLAN'
|
|
42
|
+
## Batch 1: Setup foundation
|
|
43
|
+
- Create: `src/lib.py`
|
|
44
|
+
- Test: `tests/test_lib.py`
|
|
45
|
+
|
|
46
|
+
**Step 1:** Create files
|
|
47
|
+
|
|
48
|
+
## Batch 2: Core Logic
|
|
49
|
+
- Create: `src/core.py`
|
|
50
|
+
- Modify: `src/lib.py`
|
|
51
|
+
|
|
52
|
+
**Step 1:** Add core
|
|
53
|
+
PLAN
|
|
54
|
+
|
|
55
|
+
# Generate AGENTS.md
|
|
56
|
+
generate_agents_md "$WORK/plan.md" "$WORK" "headless"
|
|
57
|
+
|
|
58
|
+
# Test: file created
|
|
59
|
+
TESTS=$((TESTS + 1))
|
|
60
|
+
if [[ -f "$WORK/AGENTS.md" ]]; then
|
|
61
|
+
echo "PASS: AGENTS.md created"
|
|
62
|
+
else
|
|
63
|
+
echo "FAIL: AGENTS.md should be created"
|
|
64
|
+
FAILURES=$((FAILURES + 1))
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
output=$(cat "$WORK/AGENTS.md")
|
|
68
|
+
assert_contains "has batch count" "2 batches" "$output"
|
|
69
|
+
assert_contains "has mode" "headless" "$output"
|
|
70
|
+
assert_contains "has tools" "Bash" "$output"
|
|
71
|
+
assert_contains "has plan name" "plan.md" "$output"
|
|
72
|
+
assert_contains "has batch 1 title" "Setup foundation" "$output"
|
|
73
|
+
assert_contains "has batch 2 title" "Core Logic" "$output"
|
|
74
|
+
assert_contains "has guidelines" "quality gate" "$output"
|
|
75
|
+
|
|
76
|
+
# Test: team mode
|
|
77
|
+
generate_agents_md "$WORK/plan.md" "$WORK" "team"
|
|
78
|
+
output=$(cat "$WORK/AGENTS.md")
|
|
79
|
+
assert_contains "team mode updated" "team" "$output"
|
|
80
|
+
|
|
81
|
+
echo ""
|
|
82
|
+
echo "Results: $((TESTS - FAILURES))/$TESTS passed"
|
|
83
|
+
if [[ $FAILURES -gt 0 ]]; then
|
|
84
|
+
echo "FAILURES: $FAILURES"
|
|
85
|
+
exit 1
|
|
86
|
+
fi
|
|
87
|
+
echo "ALL PASSED"
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Test analyze-report.sh — verifies refactored behavior using ollama.sh
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
AR="$SCRIPT_DIR/../analyze-report.sh"
|
|
7
|
+
|
|
8
|
+
FAILURES=0
|
|
9
|
+
TESTS=0
|
|
10
|
+
|
|
11
|
+
assert_eq() {
|
|
12
|
+
local desc="$1" expected="$2" actual="$3"
|
|
13
|
+
TESTS=$((TESTS + 1))
|
|
14
|
+
if [[ "$expected" != "$actual" ]]; then
|
|
15
|
+
echo "FAIL: $desc"
|
|
16
|
+
echo " expected: $expected"
|
|
17
|
+
echo " actual: $actual"
|
|
18
|
+
FAILURES=$((FAILURES + 1))
|
|
19
|
+
else
|
|
20
|
+
echo "PASS: $desc"
|
|
21
|
+
fi
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
assert_exit() {
|
|
25
|
+
local desc="$1" expected_exit="$2"
|
|
26
|
+
shift 2
|
|
27
|
+
local actual_exit=0
|
|
28
|
+
"$@" >/dev/null 2>&1 || actual_exit=$?
|
|
29
|
+
TESTS=$((TESTS + 1))
|
|
30
|
+
if [[ "$expected_exit" != "$actual_exit" ]]; then
|
|
31
|
+
echo "FAIL: $desc"
|
|
32
|
+
echo " expected exit: $expected_exit"
|
|
33
|
+
echo " actual exit: $actual_exit"
|
|
34
|
+
FAILURES=$((FAILURES + 1))
|
|
35
|
+
else
|
|
36
|
+
echo "PASS: $desc"
|
|
37
|
+
fi
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
# === Sources shared libraries ===
|
|
41
|
+
|
|
42
|
+
TESTS=$((TESTS + 1))
|
|
43
|
+
if grep -q 'source.*lib/common.sh' "$AR"; then
|
|
44
|
+
echo "PASS: analyze-report.sh sources lib/common.sh"
|
|
45
|
+
else
|
|
46
|
+
echo "FAIL: analyze-report.sh sources lib/common.sh"
|
|
47
|
+
FAILURES=$((FAILURES + 1))
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
TESTS=$((TESTS + 1))
|
|
51
|
+
if grep -q 'source.*lib/ollama.sh' "$AR"; then
|
|
52
|
+
echo "PASS: analyze-report.sh sources lib/ollama.sh"
|
|
53
|
+
else
|
|
54
|
+
echo "FAIL: analyze-report.sh sources lib/ollama.sh"
|
|
55
|
+
FAILURES=$((FAILURES + 1))
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
# === Uses ollama_query ===
|
|
59
|
+
|
|
60
|
+
TESTS=$((TESTS + 1))
|
|
61
|
+
if grep -q 'ollama_query' "$AR"; then
|
|
62
|
+
echo "PASS: uses ollama_query function"
|
|
63
|
+
else
|
|
64
|
+
echo "FAIL: should use ollama_query function"
|
|
65
|
+
FAILURES=$((FAILURES + 1))
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
# === Uses ollama_extract_json ===
|
|
69
|
+
|
|
70
|
+
TESTS=$((TESTS + 1))
|
|
71
|
+
if grep -q 'ollama_extract_json' "$AR"; then
|
|
72
|
+
echo "PASS: uses ollama_extract_json function"
|
|
73
|
+
else
|
|
74
|
+
echo "FAIL: should use ollama_extract_json function"
|
|
75
|
+
FAILURES=$((FAILURES + 1))
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
# === No inline curl to Ollama ===
|
|
79
|
+
|
|
80
|
+
TESTS=$((TESTS + 1))
|
|
81
|
+
if grep -q 'curl.*api/generate' "$AR"; then
|
|
82
|
+
echo "FAIL: still has inline curl to Ollama API"
|
|
83
|
+
FAILURES=$((FAILURES + 1))
|
|
84
|
+
else
|
|
85
|
+
echo "PASS: no inline curl to Ollama API"
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# === CLI tests ===
|
|
89
|
+
|
|
90
|
+
assert_exit "no args exits 1" 1 bash "$AR"
|
|
91
|
+
assert_exit "nonexistent file exits 1" 1 bash "$AR" /nonexistent/report.md
|
|
92
|
+
|
|
93
|
+
# === Dry run works ===
|
|
94
|
+
|
|
95
|
+
WORK=$(mktemp -d)
|
|
96
|
+
trap 'rm -rf "$WORK"' EXIT
|
|
97
|
+
echo "# Test report" > "$WORK/report.md"
|
|
98
|
+
output=$(bash "$AR" "$WORK/report.md" --dry-run 2>&1) || true
|
|
99
|
+
TESTS=$((TESTS + 1))
|
|
100
|
+
if echo "$output" | grep -q "DRY RUN"; then
|
|
101
|
+
echo "PASS: dry-run mode works"
|
|
102
|
+
else
|
|
103
|
+
echo "FAIL: dry-run mode should output DRY RUN"
|
|
104
|
+
FAILURES=$((FAILURES + 1))
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
# === Summary ===
|
|
108
|
+
echo ""
|
|
109
|
+
echo "Results: $((TESTS - FAILURES))/$TESTS passed"
|
|
110
|
+
if [[ $FAILURES -gt 0 ]]; then
|
|
111
|
+
echo "FAILURES: $FAILURES"
|
|
112
|
+
exit 1
|
|
113
|
+
fi
|
|
114
|
+
echo "ALL PASSED"
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
5
|
+
source "$SCRIPT_DIR/test-helpers.sh"
|
|
6
|
+
|
|
7
|
+
ARCH_MAP="$SCRIPT_DIR/../architecture-map.sh"
|
|
8
|
+
|
|
9
|
+
# --- Test: --help exits 0 and mentions ARCHITECTURE-MAP.json ---
|
|
10
|
+
help_output=$("$ARCH_MAP" --help 2>&1) || true
|
|
11
|
+
assert_exit "--help exits 0" 0 "$ARCH_MAP" --help
|
|
12
|
+
assert_contains "--help mentions ARCHITECTURE-MAP.json" "ARCHITECTURE-MAP.json" "$help_output"
|
|
13
|
+
|
|
14
|
+
# --- Test: generates valid JSON from a temp project ---
|
|
15
|
+
TEST_TMPDIR=$(mktemp -d)
|
|
16
|
+
trap 'rm -rf "$TEST_TMPDIR"' EXIT
|
|
17
|
+
|
|
18
|
+
# Create a minimal project with shell + python files
|
|
19
|
+
mkdir -p "$TEST_TMPDIR/lib" "$TEST_TMPDIR/src"
|
|
20
|
+
cat > "$TEST_TMPDIR/main.sh" <<'SH'
|
|
21
|
+
#!/usr/bin/env bash
|
|
22
|
+
source lib/helpers.sh
|
|
23
|
+
echo "hello"
|
|
24
|
+
SH
|
|
25
|
+
cat > "$TEST_TMPDIR/lib/helpers.sh" <<'SH'
|
|
26
|
+
#!/usr/bin/env bash
|
|
27
|
+
helper_func() { echo "help"; }
|
|
28
|
+
SH
|
|
29
|
+
cat > "$TEST_TMPDIR/src/app.py" <<'PY'
|
|
30
|
+
from src.utils import do_thing
|
|
31
|
+
import os
|
|
32
|
+
|
|
33
|
+
def main():
|
|
34
|
+
do_thing()
|
|
35
|
+
PY
|
|
36
|
+
cat > "$TEST_TMPDIR/src/utils.py" <<'PY'
|
|
37
|
+
def do_thing():
|
|
38
|
+
pass
|
|
39
|
+
PY
|
|
40
|
+
|
|
41
|
+
# Run architecture-map on the temp project
|
|
42
|
+
map_exit=0
|
|
43
|
+
"$ARCH_MAP" --project-root "$TEST_TMPDIR" > /dev/null 2>&1 || map_exit=$?
|
|
44
|
+
assert_eq "generates map exit 0" "0" "$map_exit"
|
|
45
|
+
|
|
46
|
+
# Check output file exists
|
|
47
|
+
output_file="$TEST_TMPDIR/docs/ARCHITECTURE-MAP.json"
|
|
48
|
+
TESTS=$((TESTS + 1))
|
|
49
|
+
if [[ -f "$output_file" ]]; then
|
|
50
|
+
echo "PASS: creates docs/ARCHITECTURE-MAP.json"
|
|
51
|
+
else
|
|
52
|
+
echo "FAIL: docs/ARCHITECTURE-MAP.json not found"
|
|
53
|
+
FAILURES=$((FAILURES + 1))
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
# Check JSON is valid
|
|
57
|
+
json_valid=0
|
|
58
|
+
jq . "$output_file" > /dev/null 2>&1 || json_valid=1
|
|
59
|
+
assert_eq "output is valid JSON" "0" "$json_valid"
|
|
60
|
+
|
|
61
|
+
# Check required fields
|
|
62
|
+
has_generated=$(jq 'has("generated_at")' "$output_file" 2>/dev/null)
|
|
63
|
+
assert_eq "JSON has generated_at field" "true" "$has_generated"
|
|
64
|
+
|
|
65
|
+
has_modules=$(jq 'has("modules")' "$output_file" 2>/dev/null)
|
|
66
|
+
assert_eq "JSON has modules field" "true" "$has_modules"
|
|
67
|
+
|
|
68
|
+
# Check shell source dependency detected
|
|
69
|
+
source_deps=$(jq -r '[.modules[].files[]? | select(.dependencies[]? | contains("lib/helpers.sh"))] | length' "$output_file" 2>/dev/null || echo "0")
|
|
70
|
+
TESTS=$((TESTS + 1))
|
|
71
|
+
if [[ "$source_deps" -gt 0 ]]; then
|
|
72
|
+
echo "PASS: detects shell source dependencies"
|
|
73
|
+
else
|
|
74
|
+
echo "FAIL: did not detect shell source dependency on lib/helpers.sh"
|
|
75
|
+
echo " JSON: $(cat "$output_file")"
|
|
76
|
+
FAILURES=$((FAILURES + 1))
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
# --- Test: empty project produces empty modules, exits 0 ---
|
|
80
|
+
EMPTY_DIR=$(mktemp -d)
|
|
81
|
+
empty_exit=0
|
|
82
|
+
"$ARCH_MAP" --project-root "$EMPTY_DIR" > /dev/null 2>&1 || empty_exit=$?
|
|
83
|
+
assert_eq "empty project exits 0" "0" "$empty_exit"
|
|
84
|
+
|
|
85
|
+
empty_modules=$(jq '.modules | length' "$EMPTY_DIR/docs/ARCHITECTURE-MAP.json" 2>/dev/null || echo "-1")
|
|
86
|
+
assert_eq "empty project has 0 modules" "0" "$empty_modules"
|
|
87
|
+
rm -rf "$EMPTY_DIR"
|
|
88
|
+
|
|
89
|
+
report_results
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Test auto-compound.sh — verifies refactored behavior using common.sh/ollama.sh
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
AC="$SCRIPT_DIR/../auto-compound.sh"
|
|
7
|
+
|
|
8
|
+
FAILURES=0
|
|
9
|
+
TESTS=0
|
|
10
|
+
|
|
11
|
+
assert_eq() {
|
|
12
|
+
local desc="$1" expected="$2" actual="$3"
|
|
13
|
+
TESTS=$((TESTS + 1))
|
|
14
|
+
if [[ "$expected" != "$actual" ]]; then
|
|
15
|
+
echo "FAIL: $desc"
|
|
16
|
+
echo " expected: $expected"
|
|
17
|
+
echo " actual: $actual"
|
|
18
|
+
FAILURES=$((FAILURES + 1))
|
|
19
|
+
else
|
|
20
|
+
echo "PASS: $desc"
|
|
21
|
+
fi
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
assert_exit() {
|
|
25
|
+
local desc="$1" expected_exit="$2"
|
|
26
|
+
shift 2
|
|
27
|
+
local actual_exit=0
|
|
28
|
+
"$@" >/dev/null 2>&1 || actual_exit=$?
|
|
29
|
+
TESTS=$((TESTS + 1))
|
|
30
|
+
if [[ "$expected_exit" != "$actual_exit" ]]; then
|
|
31
|
+
echo "FAIL: $desc"
|
|
32
|
+
echo " expected exit: $expected_exit"
|
|
33
|
+
echo " actual exit: $actual_exit"
|
|
34
|
+
FAILURES=$((FAILURES + 1))
|
|
35
|
+
else
|
|
36
|
+
echo "PASS: $desc"
|
|
37
|
+
fi
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
# === Sources shared libraries ===
|
|
41
|
+
|
|
42
|
+
TESTS=$((TESTS + 1))
|
|
43
|
+
if grep -q 'source.*lib/common.sh' "$AC"; then
|
|
44
|
+
echo "PASS: auto-compound.sh sources lib/common.sh"
|
|
45
|
+
else
|
|
46
|
+
echo "FAIL: auto-compound.sh sources lib/common.sh"
|
|
47
|
+
FAILURES=$((FAILURES + 1))
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
TESTS=$((TESTS + 1))
|
|
51
|
+
if grep -q 'source.*lib/ollama.sh' "$AC"; then
|
|
52
|
+
echo "PASS: auto-compound.sh sources lib/ollama.sh"
|
|
53
|
+
else
|
|
54
|
+
echo "FAIL: auto-compound.sh sources lib/ollama.sh"
|
|
55
|
+
FAILURES=$((FAILURES + 1))
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
# === CLI tests ===
|
|
59
|
+
|
|
60
|
+
assert_exit "no args exits 1" 1 bash "$AC"
|
|
61
|
+
assert_exit "--help exits 0" 0 bash "$AC" /dev/null --help
|
|
62
|
+
|
|
63
|
+
# === No silent PRD discard (lesson-7) ===
|
|
64
|
+
# The old line was: > /dev/null 2>&1 || true (discard all output)
|
|
65
|
+
# New code should capture output and log errors
|
|
66
|
+
|
|
67
|
+
TESTS=$((TESTS + 1))
|
|
68
|
+
if grep -q '> /dev/null 2>&1 || true' "$AC"; then
|
|
69
|
+
echo "FAIL: PRD output still silently discarded (lesson-7 violation)"
|
|
70
|
+
FAILURES=$((FAILURES + 1))
|
|
71
|
+
else
|
|
72
|
+
echo "PASS: PRD output not silently discarded"
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
# === Uses detect_project_type in fallback ===
|
|
76
|
+
|
|
77
|
+
TESTS=$((TESTS + 1))
|
|
78
|
+
if grep -q 'detect_project_type' "$AC"; then
|
|
79
|
+
echo "PASS: uses detect_project_type for fallback detection"
|
|
80
|
+
else
|
|
81
|
+
echo "FAIL: should use detect_project_type for fallback detection"
|
|
82
|
+
FAILURES=$((FAILURES + 1))
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
# === Bug #14: head -c 40 replaced with cut -c1-40 for UTF-8 safety ===
|
|
86
|
+
|
|
87
|
+
# Verify the script uses cut -c1-40 instead of head -c 40
|
|
88
|
+
TESTS=$((TESTS + 1))
|
|
89
|
+
if grep -q 'cut -c1-40' "$AC"; then
|
|
90
|
+
echo "PASS: uses cut -c1-40 for UTF-8-safe character truncation"
|
|
91
|
+
else
|
|
92
|
+
echo "FAIL: should use cut -c1-40 instead of head -c 40"
|
|
93
|
+
FAILURES=$((FAILURES + 1))
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
TESTS=$((TESTS + 1))
|
|
97
|
+
if grep -q 'head -c' "$AC"; then
|
|
98
|
+
echo "FAIL: still contains head -c (byte-level truncation, breaks UTF-8)"
|
|
99
|
+
FAILURES=$((FAILURES + 1))
|
|
100
|
+
else
|
|
101
|
+
echo "PASS: no head -c byte truncation remaining"
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
# Functional test: multi-byte characters are not split
|
|
105
|
+
# The slug pipeline: lowercase → replace non-alnum with dash → collapse dashes → cut to 40 chars
|
|
106
|
+
# CJK and emoji get replaced by dashes in the sed step, but the cut must not corrupt them
|
|
107
|
+
# before sed processes them. Test the full pipeline expression.
|
|
108
|
+
TESTS=$((TESTS + 1))
|
|
109
|
+
SLUG_PIPELINE='tr '\''[:upper:]'\'' '\''[:lower:]'\'' | sed '\''s/[^a-z0-9]/-/g'\'' | sed '\''s/--*/-/g'\'' | cut -c1-40'
|
|
110
|
+
# Input with emoji and CJK — these become dashes after sed, but cut -c handles them correctly
|
|
111
|
+
INPUT="add-emoji-support-🚀🎉-for-notifications"
|
|
112
|
+
RESULT=$(echo "$INPUT" | eval "$SLUG_PIPELINE")
|
|
113
|
+
# Verify result is valid (no broken bytes — should be pure ASCII after sed)
|
|
114
|
+
VALID=$(echo "$RESULT" | LC_ALL=C grep -c '[^ -~]' || true)
|
|
115
|
+
if [[ "$VALID" == "0" ]]; then
|
|
116
|
+
echo "PASS: multi-byte input produces valid slug (no broken UTF-8)"
|
|
117
|
+
else
|
|
118
|
+
echo "FAIL: multi-byte input produced invalid bytes in slug"
|
|
119
|
+
echo " result: $RESULT"
|
|
120
|
+
FAILURES=$((FAILURES + 1))
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
# === Bug #19: ls -t replaced with find+sort for space-safe file selection ===
|
|
124
|
+
|
|
125
|
+
# Verify the script uses find instead of ls -t
|
|
126
|
+
TESTS=$((TESTS + 1))
|
|
127
|
+
if grep -q 'find reports/' "$AC"; then
|
|
128
|
+
echo "PASS: uses find for report file selection"
|
|
129
|
+
else
|
|
130
|
+
echo "FAIL: should use find instead of ls -t for report selection"
|
|
131
|
+
FAILURES=$((FAILURES + 1))
|
|
132
|
+
fi
|
|
133
|
+
|
|
134
|
+
TESTS=$((TESTS + 1))
|
|
135
|
+
if grep 'ls -t' "$AC" | grep -qv '^#'; then
|
|
136
|
+
echo "FAIL: still contains ls -t (breaks on filenames with spaces)"
|
|
137
|
+
FAILURES=$((FAILURES + 1))
|
|
138
|
+
else
|
|
139
|
+
echo "PASS: no ls -t for file selection remaining"
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
# Functional test: filenames with spaces
|
|
143
|
+
TESTS=$((TESTS + 1))
|
|
144
|
+
TMPDIR_SPACES=$(mktemp -d)
|
|
145
|
+
mkdir -p "$TMPDIR_SPACES/reports"
|
|
146
|
+
# Create files with spaces, newest last
|
|
147
|
+
echo "old report" > "$TMPDIR_SPACES/reports/old report.md"
|
|
148
|
+
sleep 0.1
|
|
149
|
+
echo "new report" > "$TMPDIR_SPACES/reports/my new report.md"
|
|
150
|
+
# Use the same find command from auto-compound.sh
|
|
151
|
+
FOUND=$(cd "$TMPDIR_SPACES" && find reports/ -name '*.md' -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-)
|
|
152
|
+
if [[ "$FOUND" == "reports/my new report.md" ]]; then
|
|
153
|
+
echo "PASS: find selects newest file even with spaces in name"
|
|
154
|
+
else
|
|
155
|
+
echo "FAIL: find did not select correct file with spaces"
|
|
156
|
+
echo " expected: reports/my new report.md"
|
|
157
|
+
echo " actual: $FOUND"
|
|
158
|
+
FAILURES=$((FAILURES + 1))
|
|
159
|
+
fi
|
|
160
|
+
rm -rf "$TMPDIR_SPACES"
|
|
161
|
+
|
|
162
|
+
# === Summary ===
|
|
163
|
+
echo ""
|
|
164
|
+
echo "Results: $((TESTS - FAILURES))/$TESTS passed"
|
|
165
|
+
if [[ $FAILURES -gt 0 ]]; then
|
|
166
|
+
echo "FAILURES: $FAILURES"
|
|
167
|
+
exit 1
|
|
168
|
+
fi
|
|
169
|
+
echo "ALL PASSED"
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
5
|
+
source "$SCRIPT_DIR/test-helpers.sh"
|
|
6
|
+
|
|
7
|
+
WORK=$(mktemp -d)
|
|
8
|
+
trap 'rm -rf "$WORK"' EXIT
|
|
9
|
+
|
|
10
|
+
# --- Setup: create fake project directories with Makefiles ---
|
|
11
|
+
mkdir -p "$WORK/projects/project-a"
|
|
12
|
+
mkdir -p "$WORK/projects/project-b"
|
|
13
|
+
|
|
14
|
+
# Use a unique log file for tracking which directory each project runs from
|
|
15
|
+
LOG_FILE="$WORK/cwd-log"
|
|
16
|
+
|
|
17
|
+
cat > "$WORK/projects/project-a/Makefile" << EOF
|
|
18
|
+
test:
|
|
19
|
+
@pwd >> $LOG_FILE
|
|
20
|
+
@echo "project-a tests passed"
|
|
21
|
+
EOF
|
|
22
|
+
|
|
23
|
+
cat > "$WORK/projects/project-b/Makefile" << EOF
|
|
24
|
+
test:
|
|
25
|
+
@pwd >> $LOG_FILE
|
|
26
|
+
@echo "project-b tests passed"
|
|
27
|
+
EOF
|
|
28
|
+
|
|
29
|
+
# --- Test: cd is restored between project iterations ---
|
|
30
|
+
# Run batch-test across both projects
|
|
31
|
+
output=$("$SCRIPT_DIR/../batch-test.sh" "$WORK/projects" 2>&1) || true
|
|
32
|
+
|
|
33
|
+
# Read the logged working directories
|
|
34
|
+
if [[ -f "$LOG_FILE" ]]; then
|
|
35
|
+
cwd_a=$(sed -n '1p' "$LOG_FILE")
|
|
36
|
+
cwd_b=$(sed -n '2p' "$LOG_FILE")
|
|
37
|
+
|
|
38
|
+
# Each project should run from its own directory
|
|
39
|
+
assert_contains "batch-test: project-a runs from its own dir" "project-a" "$cwd_a"
|
|
40
|
+
assert_contains "batch-test: project-b runs from its own dir" "project-b" "$cwd_b"
|
|
41
|
+
else
|
|
42
|
+
# If log file doesn't exist, both projects failed to run
|
|
43
|
+
TESTS=$((TESTS + 1))
|
|
44
|
+
echo "FAIL: batch-test: cwd log file not created"
|
|
45
|
+
FAILURES=$((FAILURES + 1))
|
|
46
|
+
TESTS=$((TESTS + 1))
|
|
47
|
+
echo "FAIL: batch-test: project-b dir check (no log)"
|
|
48
|
+
FAILURES=$((FAILURES + 1))
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
# --- Test: output includes both projects ---
|
|
52
|
+
assert_contains "batch-test: output includes project-a" "project-a" "$output"
|
|
53
|
+
assert_contains "batch-test: output includes project-b" "project-b" "$output"
|
|
54
|
+
assert_contains "batch-test: output includes Done" "Done" "$output"
|
|
55
|
+
|
|
56
|
+
# --- Test: single project target works ---
|
|
57
|
+
single_output=$("$SCRIPT_DIR/../batch-test.sh" "$WORK/projects" "project-a" 2>&1) || true
|
|
58
|
+
assert_contains "batch-test: single target runs" "project-a" "$single_output"
|
|
59
|
+
assert_not_contains "batch-test: single target skips other" "project-b" "$single_output"
|
|
60
|
+
|
|
61
|
+
# --- Test: missing project is skipped ---
|
|
62
|
+
skip_output=$("$SCRIPT_DIR/../batch-test.sh" "$WORK/projects" "nonexistent" 2>&1) || true
|
|
63
|
+
assert_contains "batch-test: missing project skipped" "SKIP" "$skip_output"
|
|
64
|
+
|
|
65
|
+
report_results
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Test benchmarks/runner.sh
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
7
|
+
RUNNER="$REPO_ROOT/benchmarks/runner.sh"
|
|
8
|
+
|
|
9
|
+
source "$SCRIPT_DIR/test-helpers.sh"
|
|
10
|
+
|
|
11
|
+
# --- Test 1: list shows benchmarks ---
|
|
12
|
+
output=$(bash "$RUNNER" list 2>&1)
|
|
13
|
+
assert_contains "list shows benchmarks" "01-rest-endpoint" "$output"
|
|
14
|
+
assert_contains "list shows all 5" "05-multi-file-feature" "$output"
|
|
15
|
+
|
|
16
|
+
# --- Test 2: help works ---
|
|
17
|
+
output=$(bash "$RUNNER" help 2>&1)
|
|
18
|
+
assert_contains "help shows usage" "Usage:" "$output"
|
|
19
|
+
|
|
20
|
+
# --- Test 3: unknown benchmark fails gracefully ---
|
|
21
|
+
exit_code=0
|
|
22
|
+
bash "$RUNNER" run nonexistent-benchmark >/dev/null 2>&1 || exit_code=$?
|
|
23
|
+
assert_eq "unknown benchmark exits non-zero" "1" "$exit_code"
|
|
24
|
+
|
|
25
|
+
report_results
|