Files
Keep/.opencode/skills/bmad-builder-setup/scripts/tests/test-merge-help-csv.py
Sepehr Ramezani fa7e166f3e feat: add reminders page, BMad skills upgrade, MCP server refactor
- Add reminders page with navigation support
- Upgrade BMad builder module to skills-based architecture
- Refactor MCP server: extract tools and auth into separate modules
- Add connections cache, custom AI provider support
- Update prisma schema and generated client
- Various UI/UX improvements and i18n updates
- Add service worker for PWA support

Made-with: Cursor
2026-04-13 21:02:53 +02:00

238 lines
9.2 KiB
Python

#!/usr/bin/env python3
# /// script
# requires-python = ">=3.9"
# dependencies = []
# ///
"""Unit tests for merge-help-csv.py."""
import csv
import os
import sys
import tempfile
import unittest
from io import StringIO
from pathlib import Path
# Import merge_help_csv module
from importlib.util import spec_from_file_location, module_from_spec
_spec = spec_from_file_location(
"merge_help_csv",
str(Path(__file__).parent.parent / "merge-help-csv.py"),
)
merge_help_csv_mod = module_from_spec(_spec)
_spec.loader.exec_module(merge_help_csv_mod)
extract_module_codes = merge_help_csv_mod.extract_module_codes
filter_rows = merge_help_csv_mod.filter_rows
read_csv_rows = merge_help_csv_mod.read_csv_rows
write_csv = merge_help_csv_mod.write_csv
cleanup_legacy_csvs = merge_help_csv_mod.cleanup_legacy_csvs
HEADER = merge_help_csv_mod.HEADER
SAMPLE_ROWS = [
["bmb", "", "bmad-bmb-module-init", "Install Module", "IM", "install", "", "Install BMad Builder.", "anytime", "", "", "false", "", "config", ""],
["bmb", "", "bmad-agent-builder", "Build Agent", "BA", "build-process", "", "Create an agent.", "anytime", "", "", "false", "output_folder", "agent skill", ""],
]
class TestExtractModuleCodes(unittest.TestCase):
def test_extracts_codes(self):
codes = extract_module_codes(SAMPLE_ROWS)
self.assertEqual(codes, {"bmb"})
def test_multiple_codes(self):
rows = SAMPLE_ROWS + [
["cis", "", "cis-skill", "CIS Skill", "CS", "run", "", "A skill.", "anytime", "", "", "false", "", "", ""],
]
codes = extract_module_codes(rows)
self.assertEqual(codes, {"bmb", "cis"})
def test_empty_rows(self):
codes = extract_module_codes([])
self.assertEqual(codes, set())
class TestFilterRows(unittest.TestCase):
def test_removes_matching_rows(self):
result = filter_rows(SAMPLE_ROWS, "bmb")
self.assertEqual(len(result), 0)
def test_preserves_non_matching_rows(self):
mixed_rows = SAMPLE_ROWS + [
["cis", "", "cis-skill", "CIS Skill", "CS", "run", "", "A skill.", "anytime", "", "", "false", "", "", ""],
]
result = filter_rows(mixed_rows, "bmb")
self.assertEqual(len(result), 1)
self.assertEqual(result[0][0], "cis")
def test_no_match_preserves_all(self):
result = filter_rows(SAMPLE_ROWS, "xyz")
self.assertEqual(len(result), 2)
class TestReadWriteCSV(unittest.TestCase):
def test_nonexistent_file_returns_empty(self):
header, rows = read_csv_rows("/nonexistent/path/file.csv")
self.assertEqual(header, [])
self.assertEqual(rows, [])
def test_round_trip(self):
with tempfile.TemporaryDirectory() as tmpdir:
path = os.path.join(tmpdir, "test.csv")
write_csv(path, HEADER, SAMPLE_ROWS)
header, rows = read_csv_rows(path)
self.assertEqual(len(rows), 2)
self.assertEqual(rows[0][0], "bmb")
self.assertEqual(rows[0][2], "bmad-bmb-module-init")
def test_creates_parent_dirs(self):
with tempfile.TemporaryDirectory() as tmpdir:
path = os.path.join(tmpdir, "sub", "dir", "test.csv")
write_csv(path, HEADER, SAMPLE_ROWS)
self.assertTrue(os.path.exists(path))
class TestEndToEnd(unittest.TestCase):
def _write_source(self, tmpdir, rows):
path = os.path.join(tmpdir, "source.csv")
write_csv(path, HEADER, rows)
return path
def _write_target(self, tmpdir, rows):
path = os.path.join(tmpdir, "target.csv")
write_csv(path, HEADER, rows)
return path
def test_fresh_install_no_existing_target(self):
with tempfile.TemporaryDirectory() as tmpdir:
source_path = self._write_source(tmpdir, SAMPLE_ROWS)
target_path = os.path.join(tmpdir, "target.csv")
# Target doesn't exist
self.assertFalse(os.path.exists(target_path))
# Simulate merge
_, source_rows = read_csv_rows(source_path)
source_codes = extract_module_codes(source_rows)
write_csv(target_path, HEADER, source_rows)
_, result_rows = read_csv_rows(target_path)
self.assertEqual(len(result_rows), 2)
def test_merge_into_existing_with_other_module(self):
with tempfile.TemporaryDirectory() as tmpdir:
other_rows = [
["cis", "", "cis-skill", "CIS Skill", "CS", "run", "", "A skill.", "anytime", "", "", "false", "", "", ""],
]
target_path = self._write_target(tmpdir, other_rows)
source_path = self._write_source(tmpdir, SAMPLE_ROWS)
# Read both
_, target_rows = read_csv_rows(target_path)
_, source_rows = read_csv_rows(source_path)
source_codes = extract_module_codes(source_rows)
# Anti-zombie filter + append
filtered = target_rows
for code in source_codes:
filtered = filter_rows(filtered, code)
merged = filtered + source_rows
write_csv(target_path, HEADER, merged)
_, result_rows = read_csv_rows(target_path)
self.assertEqual(len(result_rows), 3) # 1 cis + 2 bmb
def test_anti_zombie_replaces_stale_entries(self):
with tempfile.TemporaryDirectory() as tmpdir:
# Existing target has old bmb entries + cis entry
old_bmb_rows = [
["bmb", "", "old-skill", "Old Skill", "OS", "run", "", "Old.", "anytime", "", "", "false", "", "", ""],
["bmb", "", "another-old", "Another", "AO", "run", "", "Old too.", "anytime", "", "", "false", "", "", ""],
]
cis_rows = [
["cis", "", "cis-skill", "CIS Skill", "CS", "run", "", "A skill.", "anytime", "", "", "false", "", "", ""],
]
target_path = self._write_target(tmpdir, old_bmb_rows + cis_rows)
source_path = self._write_source(tmpdir, SAMPLE_ROWS)
# Read both
_, target_rows = read_csv_rows(target_path)
_, source_rows = read_csv_rows(source_path)
source_codes = extract_module_codes(source_rows)
# Anti-zombie filter + append
filtered = target_rows
for code in source_codes:
filtered = filter_rows(filtered, code)
merged = filtered + source_rows
write_csv(target_path, HEADER, merged)
_, result_rows = read_csv_rows(target_path)
# Should have 1 cis + 2 new bmb = 3 (old bmb removed)
self.assertEqual(len(result_rows), 3)
module_codes = [r[0] for r in result_rows]
self.assertEqual(module_codes.count("bmb"), 2)
self.assertEqual(module_codes.count("cis"), 1)
# Old skills should be gone
skill_names = [r[2] for r in result_rows]
self.assertNotIn("old-skill", skill_names)
self.assertNotIn("another-old", skill_names)
class TestCleanupLegacyCsvs(unittest.TestCase):
def test_deletes_module_and_core_csvs(self):
with tempfile.TemporaryDirectory() as tmpdir:
legacy_dir = os.path.join(tmpdir, "_bmad")
for subdir in ("core", "bmb"):
d = os.path.join(legacy_dir, subdir)
os.makedirs(d)
with open(os.path.join(d, "module-help.csv"), "w") as f:
f.write("header\nrow\n")
deleted = cleanup_legacy_csvs(legacy_dir, "bmb")
self.assertEqual(len(deleted), 2)
self.assertFalse(os.path.exists(os.path.join(legacy_dir, "core", "module-help.csv")))
self.assertFalse(os.path.exists(os.path.join(legacy_dir, "bmb", "module-help.csv")))
# Directories still exist
self.assertTrue(os.path.isdir(os.path.join(legacy_dir, "core")))
self.assertTrue(os.path.isdir(os.path.join(legacy_dir, "bmb")))
def test_leaves_other_module_csvs_alone(self):
with tempfile.TemporaryDirectory() as tmpdir:
legacy_dir = os.path.join(tmpdir, "_bmad")
for subdir in ("bmb", "cis"):
d = os.path.join(legacy_dir, subdir)
os.makedirs(d)
with open(os.path.join(d, "module-help.csv"), "w") as f:
f.write("header\nrow\n")
deleted = cleanup_legacy_csvs(legacy_dir, "bmb")
self.assertEqual(len(deleted), 1) # only bmb, not cis
self.assertTrue(os.path.exists(os.path.join(legacy_dir, "cis", "module-help.csv")))
def test_no_legacy_files_returns_empty(self):
with tempfile.TemporaryDirectory() as tmpdir:
deleted = cleanup_legacy_csvs(tmpdir, "bmb")
self.assertEqual(deleted, [])
def test_handles_only_core_no_module(self):
with tempfile.TemporaryDirectory() as tmpdir:
legacy_dir = os.path.join(tmpdir, "_bmad")
core_dir = os.path.join(legacy_dir, "core")
os.makedirs(core_dir)
with open(os.path.join(core_dir, "module-help.csv"), "w") as f:
f.write("header\nrow\n")
deleted = cleanup_legacy_csvs(legacy_dir, "bmb")
self.assertEqual(len(deleted), 1)
self.assertFalse(os.path.exists(os.path.join(core_dir, "module-help.csv")))
if __name__ == "__main__":
unittest.main()