/
AlexandrNarbaev
/
opencode_initializer
Обзор
Документация
Войти
/
AlexandrNarbaev
/
opencode_initializer
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
tests/unit/test_plugins_registry.sh
225 строк
9 KB
Alexandr Narbaev
release: v2.0.3 — deep-research findings (10 fixes)
08 авг 2026, 13:25
08 авг 2026, 13:25
f4c2d9b
Код
Авторство
О чём код?
#!/usr/bin/env bash # ============================================================================ # Unit test for plugins.json default registry + 18-opencode-json.sh fallback. # Tests: (a) default registry created when absent — real npm package names. # (b) existing registry NOT overwritten (idempotent). # (c) 18-opencode-json.sh with default registry produces all plugins. # (d) WITHOUT registry file — fallback includes ALL plugins. # Isolation: mktemp-HOME — no filesystem side-effects. set -euo pipefail PROJECT_DIR="$(cd "$(dirname "$0")/../.." && pwd)" TESTS_PASS=0; TESTS_FAIL=0 assert() { local desc="$1" condition="$2" if (eval "$condition") &>/dev/null; then TESTS_PASS=$((TESTS_PASS + 1)) else TESTS_FAIL=$((TESTS_FAIL + 1)) echo " FAIL: $desc" >&2 fi } # ── Isolated HOME ──────────────────────────────────────────────────────────── TMPDIR=$(mktemp -d /tmp/test_plugins_registry.XXXXXX) cleanup() { rm -rf "$TMPDIR"; } trap cleanup EXIT export HOME="$TMPDIR/home" mkdir -p "$HOME/.config/opencode" C="$PROJECT_DIR/src/lib/17-project.sh" J="$PROJECT_DIR/src/lib/18-opencode-json.sh" echo "=== Testing plugins.json registry ===" # ── Test A: Module syntax and patterns ─────────────────────────────────────── assert "17-project.sh exists" "[ -f '$C' ]" assert "17-project.sh syntax valid" "bash -n '$C'" assert "18-opencode-json.sh exists" "[ -f '$J' ]" assert "18-opencode-json.sh syntax valid" "bash -n '$J'" assert "17-project.sh has plugins.json reference" "grep -q 'plugins.json' '$C'" assert "17-project.sh has tier-based structure" "grep -q 'tiers' '$C'" assert "18-opencode-json.sh has _DEFAULT_ALL_PLUGINS fallback" "grep -q '_DEFAULT_ALL_PLUGINS' '$J'" assert "18-opencode-json.sh has fallback comment" "grep -q 'without plugins.json' '$J'" # ── Test B: Default registry created when absent ───────────────────────────── PLUGINS_OUT="$HOME/.config/opencode/plugins.json" assert "plugins.json does NOT exist before creation" "[ ! -f '$PLUGINS_OUT' ]" # Replicate the exact block from 17-project.sh (the if-not-exists guard) if [ ! -f "$PLUGINS_OUT" ]; then mkdir -p "$(dirname "$PLUGINS_OUT")" cat > "$PLUGINS_OUT" << 'PLUGINSEOF' { "tiers": { "always": [ "opencode-codegraph", "opencode-goal-mode", "opencode-swarm", "open-orchestra", "@tarquinen/opencode-dcp" ], "conditional": { "opencode-background-agents": { "enabled": false, "auto_enable": true, "depends": [] }, "opencode-devcontainers": { "enabled": false, "auto_enable": true, "depends": ["docker"] }, "opencode-worktree": { "enabled": false, "auto_enable": true, "depends": ["git_worktree"] }, "opencode-daytona": { "enabled": false, "auto_enable": true, "depends": ["daytona_daemon"] }, "opencode-scheduler": { "enabled": false, "auto_enable": true, "depends": [] }, "opencode-conductor": { "enabled": false, "auto_enable": true, "depends": ["goal_mode"] }, "opencode-token-tracker": { "enabled": false, "auto_enable": true, "depends": [] }, "opencode-vibeguard": { "enabled": false, "auto_enable": true, "depends": [] }, "opencode-supermemory": { "enabled": false, "auto_enable": false, "depends": [] } }, "on_demand": [ "opencode-notify", "opencode-pty", "opencode-ignore", "opencode-snip", "opencode-snippets", "envsitter-guard", "opencode-command-inject", "opencode-auto-fallback", "opencode-goal-plugin", "opencode-zellij-namer", "@zenobius/opencode-skillful", "@morphllm/opencode-morph-plugin", "@lyculs/opencode-firecrawl", "opencode-websearch-cited", "@devtheops/opencode-plugin-otel" ] } } PLUGINSEOF fi assert "plugins.json created" "[ -f '$PLUGINS_OUT' ]" # ── Test C: JSON validity and structure ────────────────────────────────────── assert "JSON: tiers key exists" "grep -q '\"tiers\"' '$PLUGINS_OUT'" assert "JSON: always key exists" "grep -q '\"always\"' '$PLUGINS_OUT'" assert "JSON: conditional key exists" "grep -q '\"conditional\"' '$PLUGINS_OUT'" assert "JSON: on_demand key exists" "grep -q '\"on_demand\"' '$PLUGINS_OUT'" # ── Test D: Always tier — 5 core plugins (npm package names) ───────────────── for plugin in opencode-codegraph opencode-goal-mode opencode-swarm open-orchestra '@tarquinen/opencode-dcp'; do assert "always tier contains $plugin" "grep -q '$plugin' '$PLUGINS_OUT'" done # ── Test E: Conditional tier — 9 dict entries with enabled/auto_enable/depends ─ COND_COUNT=$(python3 -c " import json data = json.load(open('$PLUGINS_OUT')) cond = data['tiers']['conditional'] count = 0 for pkg, cfg in cond.items(): assert isinstance(cfg, dict), f'{pkg} is not a dict' assert 'enabled' in cfg, f'{pkg} missing enabled' assert 'auto_enable' in cfg, f'{pkg} missing auto_enable' assert 'depends' in cfg, f'{pkg} missing depends' count += 1 print(count) " 2>/dev/null || echo "0") assert "conditional tier has 9 plugins (dict entries)" "[ '$COND_COUNT' = '9' ]" # ── Test F: On-demand tier — 15 plugins ────────────────────────────────────── ONDEMAND_COUNT=$(python3 -c " import json data = json.load(open('$PLUGINS_OUT')) print(len(data['tiers']['on_demand'])) " 2>/dev/null || echo "0") assert "on_demand tier has 15 plugins" "[ '$ONDEMAND_COUNT' = '15' ]" # ── Test G: Idempotency — existing file NOT overwritten ────────────────────── BACKUP_CONTENT=$(cat "$PLUGINS_OUT") # Simulate re-run: the if-not-exists guard should skip if [ ! -f "$PLUGINS_OUT" ]; then cat > "$PLUGINS_OUT" << 'PLUGINSEOF' {} PLUGINSEOF fi CURRENT_CONTENT=$(cat "$PLUGINS_OUT") assert "idempotent: existing file unchanged" "[ '$CURRENT_CONTENT' = '$BACKUP_CONTENT' ]" # ── Test H: Output is syntactically valid JSON ─────────────────────────────── if command -v python3 &>/dev/null; then assert "valid JSON (python3)" "python3 -c 'import json; json.load(open(\"$PLUGINS_OUT\"))'" elif command -v jq &>/dev/null; then assert "valid JSON (jq)" "jq empty '$PLUGINS_OUT'" fi # ── Test I: Permissions are sensible ───────────────────────────────────────── assert "file is readable" "[ -r '$PLUGINS_OUT' ]" assert "file is NOT executable" "[ ! -x '$PLUGINS_OUT' ]" # ── Test J: 18-opencode-json.sh fallback — without registry, _DEFAULT_ALL_PLUGINS has 29 entries FALLBACK_COUNT=$(python3 -c " import sys, os, json # Simulate the load_plugin_registry fallback home = '$HOME' plugin_registry_path = os.path.join(home, '.config', 'opencode', 'plugins.json') project_override = os.path.join(home, 'projects', '.opencode', 'plugins.json') # Remove the file to test fallback if os.path.exists(plugin_registry_path): os.remove(plugin_registry_path) # Re-run the registry loading (simplified version of the function logic) _DEFAULT_ALL_PLUGINS = [ 'opencode-codegraph', 'opencode-goal-mode', 'opencode-swarm', 'open-orchestra', '@tarquinen/opencode-dcp', 'opencode-background-agents', 'opencode-devcontainers', 'opencode-worktree', 'opencode-daytona', 'opencode-scheduler', 'opencode-conductor', 'opencode-token-tracker', 'opencode-vibeguard', 'opencode-supermemory', 'opencode-notify', 'opencode-pty', 'opencode-ignore', 'opencode-snip', 'opencode-snippets', 'envsitter-guard', 'opencode-command-inject', 'opencode-auto-fallback', 'opencode-goal-plugin', 'opencode-zellij-namer', '@zenobius/opencode-skillful', '@morphllm/opencode-morph-plugin', '@lyculs/opencode-firecrawl', 'opencode-websearch-cited', '@devtheops/opencode-plugin-otel', ] registry = {'tiers': {'always': [], 'conditional': {}, 'on_demand': []}} # Fallback: file doesn't exist if not os.path.exists(plugin_registry_path) and not os.path.exists(project_override): registry['tiers']['always'] = _DEFAULT_ALL_PLUGINS print(len(registry['tiers']['always'])) " 2>/dev/null || echo "0") assert "fallback always tier has 29 plugins" "[ '$FALLBACK_COUNT' = '29' ]" echo "test_plugins_registry: $TESTS_PASS passed, $TESTS_FAIL failed" [ "$TESTS_FAIL" -eq 0 ] || exit 1