From 3ce37efd9888b85167001db95f63e5438d50f251 Mon Sep 17 00:00:00 2001 From: fukukei23 Date: Mon, 27 Jul 2026 00:04:31 +0900 Subject: [PATCH] =?UTF-8?q?chore:=20=E6=9C=AA=E5=AE=8C=E6=88=90=E3=82=A8?= =?UTF-8?q?=E3=83=B3=E3=83=88=E3=83=AA=E3=83=9D=E3=82=A4=E3=83=B3=E3=83=88?= =?UTF-8?q?=E3=81=AE=E6=A3=9A=E5=8D=B8=E3=81=97=EF=BC=88main=5Fcli.py?= =?UTF-8?q?=E4=BB=A5=E5=A4=96=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit app.py:73(nexus CLI)の戻り値契約ズレバグ修正(PR #106)を機に、 他のエントリポイントに同種バグが眠っていないか全経路を監査。 - nexus CLIの他コマンド・unified_gradio_ui.py(Dynamic Runタブ含む)・ bootstrap_apikey.pyは契約ズレなしと確認 - src/main_ui.py を削除: 2025-01「4.5 UI統合」でunified_gradio_ui.pyに 統合された後の抜け殻。フォールバック先モジュールはdb0424d8で no imports found確認済みで既に削除済みのため到達不能 - src/dev_tools/test_manager.py を削除: 存在しないモジュールをimportし 確実にImportErrorで落ちる・他から一切参照なし - tests/ui/test_main_ui.py・test_main_ui_unit.py を削除: main_ui.py専用のカバレッジ稼ぎ用テスト(実体テストなし) テスト: tests/ui,tests/tools 90 passed / フルスイート4904 passed, 1 failed(既存・MiniMaxモデル名の無関係な古いテスト) Co-Authored-By: Claude Sonnet 5 --- ...11\346\233\264\345\261\245\346\255\264.md" | 11 ++ src/dev_tools/test_manager.py | 66 ------- src/main_ui.py | 69 ------- tests/ui/test_main_ui.py | 185 ------------------ tests/ui/test_main_ui_unit.py | 63 ------ 5 files changed, 11 insertions(+), 383 deletions(-) delete mode 100644 src/dev_tools/test_manager.py delete mode 100644 src/main_ui.py delete mode 100644 tests/ui/test_main_ui.py delete mode 100644 tests/ui/test_main_ui_unit.py diff --git "a/docs/\345\244\211\346\233\264\345\261\245\346\255\264.md" "b/docs/\345\244\211\346\233\264\345\261\245\346\255\264.md" index 459756ee..998a1e99 100644 --- "a/docs/\345\244\211\346\233\264\345\261\245\346\255\264.md" +++ "b/docs/\345\244\211\346\233\264\345\261\245\346\255\264.md" @@ -5,6 +5,17 @@ NexusCore のプロジェクト固有変更履歴。 --- +## [2026-07-26] - 未完成エントリポイントの棚卸し(main_cli.py以外) + +### Removed +- `src/main_ui.py` を削除 — 2025-01「4.5 UI統合」で `unified_gradio_ui.py` に統合された後の抜け殻。フォールバック先の `app_ui.py`/`revision_loop.py`/`streamlit_migrated_tab.py`/`interactive_generator.py`(`src/gradio_app/`・`src/modules/` 配下)は `db0424d8`(no imports found確認済み・archive/ごと削除)で既に消滅済みで、参照先自体が存在しないため到達不能。現行の起動経路は `unified_gradio_ui.py` 直接起動(AGENTS.md/CLAUDE.md記載)で完全代替済み +- `src/dev_tools/test_manager.py` を削除 — `code_generator`/`diff_viewer`/`tester`/`whisper_handler` をimportするが、これらのモジュールはリポジトリ全体のどこにも存在せず、import時点で確実に `ImportError` → `sys.exit(1)`。他のどこからも参照されておらず、稼働実績なし +- `tests/ui/test_main_ui.py`・`tests/ui/test_main_ui_unit.py` を削除 — `main_ui.py` 専用のカバレッジ稼ぎ用テスト(`tkinter`ベースの存在しない関数を`hasattr`チェックするのみ・実体テストなし)。対象モジュール削除に伴い道連れ削除 +- 経緯: `app.py:73`(`nexus` CLI)の戻り値契約ズレバグ修正(2026-07-21・PR #106)を機に、「他のエントリポイントにも同種バグが眠っている可能性」を全経路棚卸し。`nexus` CLIの他コマンド・`unified_gradio_ui.py`(Dynamic Runタブ含む)・`bootstrap_apikey.py`は契約ズレなしと確認、上記2ファイルのみ「デッド経路」として検出 +- 詳細: `01_DECISIONS/NexusCore/2026-07-26_未完成エントリポイントの棚卸し.md`(※記録予定) + +--- + ## [2026-07-26] - CoderAgent説明文出力の根源改善(案X′・コードブロック必須化) ### Changed diff --git a/src/dev_tools/test_manager.py b/src/dev_tools/test_manager.py deleted file mode 100644 index 8f164286..00000000 --- a/src/dev_tools/test_manager.py +++ /dev/null @@ -1,66 +0,0 @@ -# test_manager.py -import os -import sys - -from dotenv import load_dotenv - -# 環境変数読み込み -load_dotenv() -api_key = os.getenv("OPENAI_API_KEY") - -# モジュールパスを追加(src配下を明示) -BASE_DIR = os.path.dirname(os.path.dirname(__file__)) # src/ -sys.path.append(BASE_DIR) -sys.path.append(os.path.join(BASE_DIR, "modules")) - -# モジュールインポート(例) -try: - from code_generator import generate_code_from_text - from diff_viewer import generate_diff - from tester import save_and_test_code - from whisper_handler import transcribe_audio -except ImportError as e: - print(f"❌ モジュールの読み込みに失敗しました: {e}") - sys.exit(1) - - -# テスト関数 -def run_all_tests(audio_path=None, transcript_text=None): - if not api_key: - print("❌ .envにOPENAI_API_KEYが定義されていません。") - return - - print("✅ OpenCodeInterpreter テスト開始\n") - - if audio_path: - print(f"🎤 音声ファイル文字起こし: {audio_path}") - transcript = transcribe_audio(audio_path) - elif transcript_text: - print(f"📝 指定されたテキストからコード生成:{transcript_text}") - transcript = transcript_text - else: - print("⚠️ 音声ファイルまたはテキストを指定してください。") - return - - print("\n🧠 GPTコード生成中...") - code = generate_code_from_text(transcript) - print("\n" + code) - - print("\n🧪 テスト実行中...") - result = save_and_test_code(code) - print("\n" + result) - - print("\n🔍 差分表示...") - diff = generate_diff("", code) - print(diff) - - print("\n✅ テスト完了") - - -# 実行例(任意の音声 or テキストで切り替え) -if __name__ == "__main__": - # audio_path = os.path.join(BASE_DIR, "sandbox_output", "sample_audio.wav") - audio_path = None # 音声ファイルがない場合は None - transcript_text = "偶数か奇数かを判定するPython関数を作成して" - - run_all_tests(audio_path, transcript_text) diff --git a/src/main_ui.py b/src/main_ui.py deleted file mode 100644 index 478b4393..00000000 --- a/src/main_ui.py +++ /dev/null @@ -1,69 +0,0 @@ -import os -import sys - -import gradio as gr - -# src ディレクトリの相対パスから modules と gradio_app を含める -sys.path.append(os.path.join(os.path.dirname(__file__), "./gradio_app")) -sys.path.append(os.path.join(os.path.dirname(__file__), "./modules")) - -# 4.5: 統合 Gradio UI を優先的に使用 -try: - from nexuscore.ui.unified_gradio_ui import launch_unified_ui - - HAS_UNIFIED_UI = True -except ImportError: - HAS_UNIFIED_UI = False - launch_unified_ui = None - -# 既存のUIタブ(フォールバック用) -try: - from app_ui import launch_app_ui - from revision_loop import launch_revision_ui - from streamlit_migrated_tab import tab_streamlit_port - - HAS_LEGACY_UI = True -except ImportError: - HAS_LEGACY_UI = False - -# interactive_generator が存在する場合にのみ読み込む -try: - from interactive_generator import app as generator_app - - has_generator = True -except ImportError: - has_generator = False - - -def launch_all_tabs(): - """ - 4.5: 統合 Gradio UI を起動(フォールバック: 既存のタブ構成) - """ - if HAS_UNIFIED_UI and launch_unified_ui: - # 4.5: 統合 UI を使用 - launch_unified_ui() - elif HAS_LEGACY_UI: - # フォールバック: 既存のタブ構成 - with gr.Blocks(title="OpenCodeInterpreter") as demo: - with gr.Tab("🧠 コード修正 + テスト"): - launch_app_ui() - - with gr.Tab("🔁 修正ループ"): - launch_revision_ui() - - with gr.Tab("🎙️ Whisper + GPTチャット"): - tab_streamlit_port() - - if has_generator: - with gr.Tab("🪄 生成タブ(任意)"): - demo += ( - generator_app # ← generator_app を .launch() ではなく Blocks としてマウント - ) - - demo.launch() - else: - print("Error: No UI available. Please check imports.") - - -if __name__ == "__main__": - launch_all_tabs() diff --git a/tests/ui/test_main_ui.py b/tests/ui/test_main_ui.py deleted file mode 100644 index 9818342e..00000000 --- a/tests/ui/test_main_ui.py +++ /dev/null @@ -1,185 +0,0 @@ -# ============================================================================== -# ファイル名: test_main_ui.py (20%突破重要要素) -# 配置場所: tests/ -# メモ: 26行のmain_ui.py完全攻略・+1.3%カバレッジ向上・UI機能テスト -# メインUI機能の包括的テスト・ユーザーインターフェース品質保証 -# ============================================================================== - -import unittest -from unittest.mock import MagicMock, patch - -try: - import main_ui - import tkinter # noqa: F401 — verify tkinter is actually available -except ImportError: - main_ui = None - - -class TestMainUI(unittest.TestCase): - """メインUI機能のテスト。""" - - def setUp(self): - """テスト実行前の初期化。""" - self.test_title = "NexusCore Test UI" - self.test_geometry = "800x600" - - def test_main_ui_import(self): - """メインUIモジュールのインポートテスト。""" - try: - import main_ui as ui - - self.assertIsNotNone(ui) - except ImportError: - self.skipTest("メインUIモジュールのインポートに失敗") - - def test_main_ui_structure(self): - """メインUIモジュールの構造テスト。""" - if main_ui is None: - self.skipTest("メインUIモジュールが利用できません") - - # モジュールの基本属性確認 - module_attributes = dir(main_ui) - self.assertIsInstance(module_attributes, list) - self.assertGreater(len(module_attributes), 0) - - def test_ui_functions(self): - """UI関連関数のテスト。""" - if main_ui is None: - self.skipTest("メインUIモジュールが利用できません") - - # 期待される関数名 - ui_functions = [ - "create_window", - "setup_ui", - "main_window", - "init_interface", - "build_gui", - "launch_ui", - "create_widgets", - "setup_layout", - "run_app", - ] - - for func_name in ui_functions: - if hasattr(main_ui, func_name): - func = getattr(main_ui, func_name) - self.assertTrue(callable(func)) - - @unittest.skipIf(main_ui is None, "main_ui module not available") - @patch("tkinter.Tk") - def test_window_creation(self, mock_tk): - """ウィンドウ作成機能のテスト。""" - if main_ui is None: - self.skipTest("メインUIモジュールが利用できません") - - # Tkinterウィンドウのモック設定 - mock_window = MagicMock() - mock_tk.return_value = mock_window - - window_functions = ["create_window", "main_window"] - - for func_name in window_functions: - if hasattr(main_ui, func_name): - with self.subTest(function=func_name): - func = getattr(main_ui, func_name) - try: - result = func() - if result is not None: - self.assertIsInstance(result, (object, type(None))) - except Exception: - # ウィンドウ作成エラーは許容 - pass - - @unittest.skipIf(main_ui is None, "main_ui module not available") - @patch("tkinter.ttk.Button") - @patch("tkinter.ttk.Label") - def test_widget_creation(self, mock_label, mock_button): - """ウィジェット作成機能のテスト。""" - if main_ui is None: - self.skipTest("メインUIモジュールが利用できません") - - widget_functions = ["create_widgets", "setup_components", "build_interface"] - - for func_name in widget_functions: - if hasattr(main_ui, func_name): - with self.subTest(function=func_name): - func = getattr(main_ui, func_name) - try: - result = func() - if result is not None: - self.assertIsInstance(result, (dict, list, tuple)) - except Exception: - # ウィジェット作成エラーは許容 - pass - - def test_ui_configuration(self): - """UI設定機能のテスト。""" - if main_ui is None: - self.skipTest("メインUIモジュールが利用できません") - - config_functions = ["configure_ui", "set_theme", "apply_styles"] - - for func_name in config_functions: - if hasattr(main_ui, func_name): - with self.subTest(function=func_name): - func = getattr(main_ui, func_name) - try: - result = func() - if result is not None: - self.assertIsInstance(result, (bool, str, dict)) - except Exception: - # UI設定エラーは許容 - pass - - @unittest.skipIf(main_ui is None, "main_ui module not available") - @patch("tkinter.messagebox.showinfo") - def test_ui_interactions(self, mock_messagebox): - """UIインタラクション機能のテスト。""" - if main_ui is None: - self.skipTest("メインUIモジュールが利用できません") - - interaction_functions = ["handle_click", "on_button_press", "process_input"] - - for func_name in interaction_functions: - if hasattr(main_ui, func_name): - with self.subTest(function=func_name): - func = getattr(main_ui, func_name) - try: - result = func("test_event") - if result is not None: - self.assertIsInstance(result, (bool, str, dict)) - except Exception: - # インタラクションエラーは許容 - pass - - -class TestMainUIAdvanced(unittest.TestCase): - """メインUIの高度な機能テスト。""" - - def test_ui_layout_management(self): - """UIレイアウト管理のテスト。""" - if main_ui is None: - self.skipTest("メインUIモジュールが利用できません") - - layout_functions = ["setup_layout", "arrange_widgets", "grid_layout"] - - for func_name in layout_functions: - if hasattr(main_ui, func_name): - func = getattr(main_ui, func_name) - self.assertTrue(callable(func)) - - def test_ui_event_handling(self): - """UIイベント処理のテスト。""" - if main_ui is None: - self.skipTest("メインUIモジュールが利用できません") - - event_functions = ["bind_events", "handle_events", "process_events"] - - for func_name in event_functions: - if hasattr(main_ui, func_name): - func = getattr(main_ui, func_name) - self.assertTrue(callable(func)) - - -if __name__ == "__main__": - unittest.main(verbosity=2) diff --git a/tests/ui/test_main_ui_unit.py b/tests/ui/test_main_ui_unit.py deleted file mode 100644 index 65acb9bf..00000000 --- a/tests/ui/test_main_ui_unit.py +++ /dev/null @@ -1,63 +0,0 @@ -"""Unit tests for main_ui.py""" - -import sys -from pathlib import Path - -import pytest - -# プロジェクトルートをパスに追加 -project_root = Path(__file__).parent.parent -sys.path.insert(0, str(project_root / "src")) - - -def test_main_ui_import(): - """main_ui.pyのインポートテスト""" - try: - import main_ui - - assert main_ui is not None - except ImportError as e: - pytest.skip(f"main_ui.pyのインポートに失敗: {e}") - - -def test_launch_all_tabs_function_exists(): - """launch_all_tabs関数の存在確認""" - try: - import main_ui - - assert hasattr(main_ui, "launch_all_tabs") - assert callable(main_ui.launch_all_tabs) - except ImportError: - pytest.skip("main_ui.pyがインポートできません") - - -def test_launch_all_tabs_basic(): - """launch_all_tabsの基本動作テスト(インポートエラーはスキップ)""" - pytest.skip("main_ui.pyは多くの依存関係があり、完全なモックが困難なためスキップ") - - -def test_launch_all_tabs_without_generator(): - """generatorがない場合のテスト(インポートエラーはスキップ)""" - pytest.skip("main_ui.pyは多くの依存関係があり、完全なモックが困難なためスキップ") - - -def test_launch_all_tabs_with_generator(): - """generatorがある場合のテスト(インポートエラーはスキップ)""" - pytest.skip("main_ui.pyは多くの依存関係があり、完全なモックが困難なためスキップ") - - -def test_launch_all_tabs_demo_launch(): - """demo.launch()が呼ばれることを確認するテスト(インポートエラーはスキップ)""" - pytest.skip("main_ui.pyは多くの依存関係があり、完全なモックが困難なためスキップ") - - -def test_main_ui_imports(): - """main_ui.pyのインポートが正常に動作することを確認""" - try: - import main_ui - - # 主要な関数や変数が存在することを確認 - assert hasattr(main_ui, "launch_all_tabs") - assert hasattr(main_ui, "has_generator") - except ImportError as e: - pytest.skip(f"main_ui.pyのインポートに失敗: {e}")