mirror of
https://github.com/obra/superpowers.git
synced 2026-07-03 16:19:05 +08:00
Compare commits
4 Commits
codex/pri-
...
fix/render
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4ab46fe700 | ||
|
|
c3847f63d7 | ||
|
|
592dd0215a | ||
|
|
6561afc87d |
@@ -242,10 +242,6 @@ git -C "$REPO_ROOT" archive --format=tar "$REF" -- \
|
|||||||
VERSION="$(jq -r '.version // empty' "$STAGE/.codex-plugin/plugin.json")"
|
VERSION="$(jq -r '.version // empty' "$STAGE/.codex-plugin/plugin.json")"
|
||||||
[[ -n "$VERSION" ]] || die "could not read version from .codex-plugin/plugin.json"
|
[[ -n "$VERSION" ]] || die "could not read version from .codex-plugin/plugin.json"
|
||||||
|
|
||||||
if jq -e 'has("hooks")' "$STAGE/.codex-plugin/plugin.json" >/dev/null; then
|
|
||||||
die "Codex manifest must not declare hooks for the portal package"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -z "$OUTPUT" ]]; then
|
if [[ -z "$OUTPUT" ]]; then
|
||||||
case "$FORMAT" in
|
case "$FORMAT" in
|
||||||
zip)
|
zip)
|
||||||
|
|||||||
@@ -13,9 +13,9 @@
|
|||||||
* Requires: graphviz (dot) installed on system
|
* Requires: graphviz (dot) installed on system
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const fs = require('fs');
|
import * as fs from 'fs';
|
||||||
const path = require('path');
|
import * as path from 'path';
|
||||||
const { execSync } = require('child_process');
|
import { execFileSync } from 'child_process';
|
||||||
|
|
||||||
function extractDotBlocks(markdown) {
|
function extractDotBlocks(markdown) {
|
||||||
const blocks = [];
|
const blocks = [];
|
||||||
@@ -69,7 +69,7 @@ ${bodies.join('\n\n')}
|
|||||||
|
|
||||||
function renderToSvg(dotContent) {
|
function renderToSvg(dotContent) {
|
||||||
try {
|
try {
|
||||||
return execSync('dot -Tsvg', {
|
return execFileSync('dot', ['-Tsvg'], {
|
||||||
input: dotContent,
|
input: dotContent,
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
maxBuffer: 10 * 1024 * 1024
|
maxBuffer: 10 * 1024 * 1024
|
||||||
@@ -107,9 +107,10 @@ function main() {
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if dot is available
|
// Check if dot is available. Run the binary directly rather than probing
|
||||||
|
// with `which`, which is not a command on Windows.
|
||||||
try {
|
try {
|
||||||
execSync('which dot', { encoding: 'utf-8' });
|
execFileSync('dot', ['-V'], { stdio: 'ignore' });
|
||||||
} catch {
|
} catch {
|
||||||
console.error('Error: graphviz (dot) not found. Install with:');
|
console.error('Error: graphviz (dot) not found. Install with:');
|
||||||
console.error(' brew install graphviz # macOS');
|
console.error(' brew install graphviz # macOS');
|
||||||
|
|||||||
@@ -140,6 +140,9 @@ extracted="$TEST_ROOT/extracted"
|
|||||||
tar_extracted="$TEST_ROOT/tar-extracted"
|
tar_extracted="$TEST_ROOT/tar-extracted"
|
||||||
write_metadata_fixture "$metadata_source"
|
write_metadata_fixture "$metadata_source"
|
||||||
|
|
||||||
|
source_hooks="$(python3 -c 'import json; print(json.load(open("'"$REPO_ROOT"'/.codex-plugin/plugin.json")).get("hooks"))')"
|
||||||
|
assert_equals "$source_hooks" "{}" "source Codex manifest suppresses local hook auto-discovery"
|
||||||
|
|
||||||
if output="$("$SCRIPT_UNDER_TEST" --allow-dirty --metadata-source "$metadata_source" --output "$archive" 2>&1)"; then
|
if output="$("$SCRIPT_UNDER_TEST" --allow-dirty --metadata-source "$metadata_source" --output "$archive" 2>&1)"; then
|
||||||
pass "package script exits successfully"
|
pass "package script exits successfully"
|
||||||
else
|
else
|
||||||
@@ -170,7 +173,7 @@ assert_contains "$archive_paths" "assets/superpowers-small.svg" "archive include
|
|||||||
|
|
||||||
manifest_summary="$(read_archive_file "$archive" .codex-plugin/plugin.json | python3 -c 'import json,sys; data=json.load(sys.stdin); print("\t".join([data["name"], data["version"], data["skills"], str(data.get("hooks"))]))')"
|
manifest_summary="$(read_archive_file "$archive" .codex-plugin/plugin.json | python3 -c 'import json,sys; data=json.load(sys.stdin); print("\t".join([data["name"], data["version"], data["skills"], str(data.get("hooks"))]))')"
|
||||||
expected_version="$(python3 -c 'import json; print(json.load(open("'"$REPO_ROOT"'/.codex-plugin/plugin.json"))["version"])')"
|
expected_version="$(python3 -c 'import json; print(json.load(open("'"$REPO_ROOT"'/.codex-plugin/plugin.json"))["version"])')"
|
||||||
assert_equals "$manifest_summary" "superpowers $expected_version ./skills/ None" "archive manifest is current and hook-free"
|
assert_equals "$manifest_summary" "superpowers $expected_version ./skills/ $source_hooks" "archive manifest preserves source hooks"
|
||||||
|
|
||||||
skill_count="$(find "$extracted/skills" -mindepth 1 -maxdepth 1 -type d | wc -l | tr -d ' ')"
|
skill_count="$(find "$extracted/skills" -mindepth 1 -maxdepth 1 -type d | wc -l | tr -d ' ')"
|
||||||
metadata_count="$(find "$extracted/skills" -path '*/agents/openai.yaml' -type f | wc -l | tr -d ' ')"
|
metadata_count="$(find "$extracted/skills" -path '*/agents/openai.yaml' -type f | wc -l | tr -d ' ')"
|
||||||
|
|||||||
113
tests/writing-skills/test-render-graphs.sh
Executable file
113
tests/writing-skills/test-render-graphs.sh
Executable file
@@ -0,0 +1,113 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -u
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||||
|
SCRIPT_UNDER_TEST="$REPO_ROOT/skills/writing-skills/render-graphs.js"
|
||||||
|
NODE_BIN="$(command -v node)"
|
||||||
|
|
||||||
|
PASSES=0
|
||||||
|
FAILURES=0
|
||||||
|
TEST_ROOT="$(mktemp -d)"
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
rm -rf "$TEST_ROOT"
|
||||||
|
}
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
pass() {
|
||||||
|
echo " [PASS] $1"
|
||||||
|
PASSES=$((PASSES + 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
fail() {
|
||||||
|
echo " [FAIL] $1"
|
||||||
|
FAILURES=$((FAILURES + 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_contains() {
|
||||||
|
local haystack="$1"
|
||||||
|
local needle="$2"
|
||||||
|
local description="$3"
|
||||||
|
|
||||||
|
if printf '%s' "$haystack" | grep -Fq -- "$needle"; then
|
||||||
|
pass "$description"
|
||||||
|
else
|
||||||
|
fail "$description"
|
||||||
|
echo " expected to find: $needle"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_not_contains() {
|
||||||
|
local haystack="$1"
|
||||||
|
local needle="$2"
|
||||||
|
local description="$3"
|
||||||
|
|
||||||
|
if printf '%s' "$haystack" | grep -Fq -- "$needle"; then
|
||||||
|
fail "$description"
|
||||||
|
echo " did not expect to find: $needle"
|
||||||
|
else
|
||||||
|
pass "$description"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
fixture="$TEST_ROOT/fixture-skill"
|
||||||
|
mkdir -p "$fixture" "$TEST_ROOT/empty-path"
|
||||||
|
cat >"$fixture/SKILL.md" <<'EOF'
|
||||||
|
---
|
||||||
|
name: fixture-skill
|
||||||
|
---
|
||||||
|
|
||||||
|
# Fixture Skill
|
||||||
|
|
||||||
|
```dot
|
||||||
|
digraph fixture_graph {
|
||||||
|
start -> end;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "Writing-skills render-graphs tests"
|
||||||
|
|
||||||
|
missing_dot_output="$(PATH="$TEST_ROOT/empty-path" "$NODE_BIN" "$SCRIPT_UNDER_TEST" "$fixture" 2>&1)"
|
||||||
|
missing_dot_status=$?
|
||||||
|
|
||||||
|
if [[ "$missing_dot_status" -ne 0 ]]; then
|
||||||
|
pass "missing Graphviz exits non-zero"
|
||||||
|
else
|
||||||
|
fail "missing Graphviz exits non-zero"
|
||||||
|
fi
|
||||||
|
assert_contains "$missing_dot_output" "Error: graphviz (dot) not found." "missing Graphviz reports install guidance"
|
||||||
|
assert_not_contains "$missing_dot_output" "ReferenceError: require is not defined" "script runs as an ES module"
|
||||||
|
|
||||||
|
render_output="$("$NODE_BIN" "$SCRIPT_UNDER_TEST" "$fixture" 2>&1)"
|
||||||
|
render_status=$?
|
||||||
|
|
||||||
|
if [[ "$render_status" -eq 0 ]]; then
|
||||||
|
pass "fixture diagram renders"
|
||||||
|
else
|
||||||
|
fail "fixture diagram renders"
|
||||||
|
printf '%s\n' "$render_output"
|
||||||
|
fi
|
||||||
|
|
||||||
|
assert_contains "$render_output" "Found 1 diagram(s)" "reports discovered diagram"
|
||||||
|
assert_contains "$render_output" "Rendered: fixture_graph.svg" "reports rendered SVG"
|
||||||
|
|
||||||
|
if [[ -f "$fixture/diagrams/fixture_graph.svg" ]]; then
|
||||||
|
pass "writes SVG output"
|
||||||
|
else
|
||||||
|
fail "writes SVG output"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -f "$fixture/diagrams/fixture_graph.svg" ]] && grep -Fq "<svg" "$fixture/diagrams/fixture_graph.svg"; then
|
||||||
|
pass "SVG output has SVG markup"
|
||||||
|
else
|
||||||
|
fail "SVG output has SVG markup"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Results: $PASSES passed, $FAILURES failed"
|
||||||
|
|
||||||
|
if [[ "$FAILURES" -gt 0 ]]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user