Folder support, Custom theme support, Boiler Plate Code support
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
"""Convert themes from convert-themes/registry.json into src/tui/themes/*.json"""
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
REGISTRY_PATH = Path("convert-themes/registry.json")
|
||||
OUTPUT_DIR = Path("src/tui/themes")
|
||||
|
||||
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
if not REGISTRY_PATH.exists():
|
||||
print(f"Error: {REGISTRY_PATH} not found.")
|
||||
exit(1)
|
||||
|
||||
with open(REGISTRY_PATH, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
|
||||
themes_list = data.get("themes", [])
|
||||
converted_count = 0
|
||||
|
||||
for item in themes_list:
|
||||
name = item.get("name")
|
||||
if not name:
|
||||
continue
|
||||
|
||||
dark = item.get("dark") or item.get("light") or {}
|
||||
if not dark:
|
||||
continue
|
||||
|
||||
theme_id = re.sub(r'[^a-z0-9\-]', '', name.lower().replace(' ', '-'))
|
||||
if not theme_id:
|
||||
continue
|
||||
|
||||
background = dark.get("mSurfaceVariant") or dark.get("mSurface") or "#1e1e1e"
|
||||
surface = dark.get("mSurface") or "#252526"
|
||||
primary = dark.get("mPrimary") or "#3b82f6"
|
||||
primary_text = dark.get("mOnPrimary") or "#ffffff"
|
||||
secondary = dark.get("mSecondary") or "#64748b"
|
||||
accent = dark.get("mTertiary") or dark.get("mHover") or primary
|
||||
folder_header = accent
|
||||
folder_text = dark.get("mOnTertiary") or dark.get("mOnHover") or "#ffffff"
|
||||
|
||||
theme_dict = {
|
||||
"id": theme_id,
|
||||
"name": name,
|
||||
"background": background,
|
||||
"surface": surface,
|
||||
"primary": primary,
|
||||
"primary_text": primary_text,
|
||||
"secondary": secondary,
|
||||
"accent": accent,
|
||||
"folder_header": folder_header,
|
||||
"folder_text": folder_text
|
||||
}
|
||||
|
||||
out_file = OUTPUT_DIR / f"{theme_id}.json"
|
||||
with open(out_file, "w", encoding="utf-8") as f_out:
|
||||
json.dump(theme_dict, f_out, indent=2)
|
||||
converted_count += 1
|
||||
|
||||
print(f"Successfully converted {converted_count} themes to {OUTPUT_DIR}/!")
|
||||
@@ -0,0 +1,27 @@
|
||||
import asyncio
|
||||
from src.tui.app import TactiTermTUI
|
||||
|
||||
async def test_command_palette_integration():
|
||||
app = TactiTermTUI()
|
||||
async with app.run_test() as pilot:
|
||||
print("Available themes count registered with Textual App:", len(app.available_themes))
|
||||
sample_themes = list(app.available_themes.keys())[:15]
|
||||
print("Sample registered themes in App:", sample_themes)
|
||||
|
||||
# Test system commands
|
||||
commands = list(app.get_system_commands(app.screen))
|
||||
cmd_titles = [c.title for c in commands]
|
||||
print("System commands in Command Palette:", cmd_titles)
|
||||
|
||||
assert "Keys" in cmd_titles, "Keys option missing from Command Palette"
|
||||
assert "Themes" in cmd_titles, "Themes option missing from Command Palette"
|
||||
|
||||
# Test applying a theme from registered themes
|
||||
app.apply_theme("dracula")
|
||||
await pilot.pause(0.1)
|
||||
print("Main box classes after applying Dracula:", app.query_one("#main-container").classes)
|
||||
assert app.query_one("#main-container").has_class("theme-dracula")
|
||||
print("Command Palette Theme Integration test PASSED!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(test_command_palette_integration())
|
||||
@@ -0,0 +1,45 @@
|
||||
"""Integration test for multi-file code execution, linting, and prompt context formatting."""
|
||||
import unittest
|
||||
from src.core.executor import CodeExecutor
|
||||
from src.core.linter import CodeLinter
|
||||
from src.core.prompts import format_multifile_context, compress_file_content
|
||||
|
||||
class TestMultiFile(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.executor = CodeExecutor()
|
||||
self.linter = CodeLinter()
|
||||
|
||||
def test_cpp_multifile_execution(self):
|
||||
files = {
|
||||
"main.cpp": '#include "main.h"\n#include <iostream>\nint main() { printMessage(); return 0; }\n',
|
||||
"main.h": '#ifndef MAIN_H\n#define MAIN_H\n#include <iostream>\ninline void printMessage() { std::cout << "C++ Multi-File Success!"; }\n#endif\n'
|
||||
}
|
||||
res = self.executor.run("cpp", code="", stdin="", files=files)
|
||||
self.assertEqual(res.get("exit_code"), 0)
|
||||
self.assertIn("C++ Multi-File Success!", res.get("stdout"))
|
||||
|
||||
def test_python_multifile_execution(self):
|
||||
files = {
|
||||
"main.py": 'import helper\nprint(helper.get_msg())\n',
|
||||
"helper.py": 'def get_msg(): return "Python Multi-File Success!"\n'
|
||||
}
|
||||
res = self.executor.run("python", code="", stdin="", files=files)
|
||||
self.assertEqual(res.get("exit_code"), 0)
|
||||
self.assertIn("Python Multi-File Success!", res.get("stdout"))
|
||||
|
||||
def test_multifile_context_formatting(self):
|
||||
files = {
|
||||
"main.cpp": '#include "main.h"\nint main() { return 0; }',
|
||||
"main.h": '#define MSG "Hello"'
|
||||
}
|
||||
ctx = format_multifile_context(files, active_file="main.cpp")
|
||||
self.assertIn("=== File: main.cpp (Active) ===", ctx)
|
||||
self.assertIn("=== File: main.h ===", ctx)
|
||||
|
||||
def test_compression(self):
|
||||
large_code = "def foo():\n pass\n" * 100
|
||||
compressed = compress_file_content("test.py", large_code)
|
||||
self.assertIn("def foo()", compressed)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,17 @@
|
||||
from textual.theme import Theme
|
||||
from src.tui.theme_manager import theme_manager
|
||||
|
||||
print("Loaded theme manager count:", len(theme_manager.themes))
|
||||
t_sample = list(theme_manager.themes.values())[0]
|
||||
print("Sample theme data:", t_sample)
|
||||
|
||||
t_obj = Theme(
|
||||
name=t_sample["id"],
|
||||
primary=t_sample["primary"],
|
||||
secondary=t_sample.get("secondary"),
|
||||
accent=t_sample.get("accent"),
|
||||
background=t_sample["background"],
|
||||
surface=t_sample["surface"],
|
||||
dark=True
|
||||
)
|
||||
print("Created Textual Theme object successfully:", t_obj.name)
|
||||
@@ -0,0 +1,20 @@
|
||||
import asyncio
|
||||
from src.tui.app import TactiTermTUI
|
||||
from textual.widgets import OptionList
|
||||
|
||||
async def test_theme_popup():
|
||||
app = TactiTermTUI()
|
||||
async with app.run_test() as pilot:
|
||||
print("Call action_cycle_theme()...")
|
||||
app.action_cycle_theme()
|
||||
await pilot.pause(0.2)
|
||||
|
||||
main_box = app.query_one("#main-container")
|
||||
print("Is show-theme-menu in classes:", main_box.has_class("show-theme-menu"))
|
||||
|
||||
theme_list = app.query_one("#theme_list_popup", OptionList)
|
||||
print("Theme list option count:", theme_list.option_count)
|
||||
print("Focused widget ID:", getattr(app.focused, "id", None))
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(test_theme_popup())
|
||||
Reference in New Issue
Block a user