""" Test cross-distro compatibility features. This module tests the cross-distribution compatibility features including: - Dynamic GI_TYPELIB_PATH detection - Wrapper script generation with correct paths - Desktop entry configuration """ import os from pathlib import Path import pytest def get_repo_root() -> Path: """Get the repository root directory.""" # Start from current file and traverse up to find repo root current = Path(__file__).resolve() for parent in [current] + list(current.parents): # Check for common repo indicators if (parent / ".git").exists() or (parent / "install.sh").exists(): return parent # Also check if we're in a 'vocalinux' subdirectory (CI structure) if parent.name == "vocalinux" and (parent.parent / "vocalinux" / "install.sh").exists(): return parent.parent / "vocalinux" # Fallback: use parent of tests directory return current.parent.parent.parent REPO_ROOT = get_repo_root() class TestCrossDistroCompatibility: """Test cross-distro compatibility features.""" @pytest.fixture def install_sh_content(self): """Fixture to load install.sh content.""" install_sh_path = REPO_ROOT / "install.sh" if not install_sh_path.exists(): pytest.skip(f"install.sh not found at {install_sh_path}") return install_sh_path.read_text() @pytest.fixture def workflow_content(self): """Fixture to load workflow content.""" workflow_path = REPO_ROOT / ".github" / "workflows" / "unified-pipeline.yml" if not workflow_path.exists(): pytest.skip(f"Workflow file not found at {workflow_path}") return workflow_path.read_text() def test_detect_typelib_path_function_exists(self, install_sh_content): """Test that detect_typelib_path function exists in install.sh.""" assert ( "detect_typelib_path()" in install_sh_content ), "detect_typelib_path function should exist" assert ( "pkg-config --variable=typelibdir" in install_sh_content ), "Should use pkg-config for detection" def test_no_hardcoded_gi_typelib_path_in_verification(self, install_sh_content): """Test that package verification uses dynamic GI_TYPELIB_PATH.""" # The verification function should use the detected path, not hardcoded assert ( "verify_package_installed()" in install_sh_content ), "verify_package_installed function should exist" # Check that it uses GI_TYPELIB_DETECTED variable verify_section = install_sh_content[ install_sh_content.find("verify_package_installed()") : install_sh_content.find( "verify_package_installed()" ) + 500 ] assert ( "GI_TYPELIB_DETECTED" in verify_section or '"$GI_TYPELIB_DETECTED"' in verify_section ), "verify_package_installed should use GI_TYPELIB_DETECTED variable" def test_wrapper_script_uses_detected_path(self, install_sh_content): """Test that wrapper scripts use the detected GI_TYPELIB_PATH.""" # Check that wrapper script creation uses GI_TYPELIB_DETECTED assert ( "export GI_TYPELIB_PATH=$GI_TYPELIB_DETECTED" in install_sh_content ), "Wrapper script should export GI_TYPELIB_PATH with detected value" def test_desktop_entry_uses_detected_path(self, install_sh_content): """Test that desktop entry uses detected GI_TYPELIB_PATH.""" # The sed command for desktop entry should use the detected path assert ( "GI_TYPELIB_PATH=$GI_TYPELIB_DETECTED" in install_sh_content or "GI_TYPELIB_PATH=\${GI_TYPELIB_DETECTED}" in install_sh_content ), "Desktop entry sed command should use GI_TYPELIB_DETECTED" # Should NOT have hardcoded /usr/lib/girepository-1.0 in desktop entry section desktop_start = install_sh_content.find("install_desktop_entry()") if desktop_start == -1: pytest.skip("install_desktop_entry function not found") desktop_section = install_sh_content[desktop_start : desktop_start + 1000] if "sed -i" in desktop_section and "vocalinux.desktop" in desktop_section: assert ( "/usr/lib/girepository-1.0" not in desktop_section.split("sed -i")[1].split("vocalinux.desktop")[0] ), "Desktop entry should not hardcode /usr/lib/girepository-1.0 path" def test_detect_typelib_path_with_pkgconfig(self, install_sh_content): """Test that detect_typelib_path uses pkg-config when available.""" # Extract the detect_typelib_path function func_start = install_sh_content.find("detect_typelib_path() {") if func_start == -1: pytest.skip("detect_typelib_path function not found") func_end = install_sh_content.find("}", func_start) func_content = install_sh_content[func_start:func_end] # Should check for pkg-config first assert "pkg-config" in func_content, "Should check for pkg-config" assert "gobject-introspection-1.0" in func_content, "Should query gobject-introspection-1.0" def test_detect_typelib_path_fallback_paths(self, install_sh_content): """Test that detect_typelib_path has fallback paths for various distros.""" # Should have fallback paths for different distros expected_paths = [ "/usr/lib/x86_64-linux-gnu/girepository-1.0", # Ubuntu/Debian x86_64 "/usr/lib/aarch64-linux-gnu/girepository-1.0", # ARM64 "/usr/lib64/girepository-1.0", # Fedora/RHEL "/usr/lib/girepository-1.0", # Arch and fallback ] for path in expected_paths: assert path in install_sh_content, f"Should have fallback path: {path}" def test_ci_workflow_uses_dynamic_detection(self, workflow_content): """Test that CI workflow uses dynamic GI_TYPELIB_PATH detection.""" # Should use pkg-config or dynamic detection assert ( "pkg-config --variable=typelibdir" in workflow_content ), "CI workflow should use pkg-config for GI_TYPELIB_PATH" class TestResourceManagerCrossDistro: """Test ResourceManager cross-distro path handling.""" def test_resource_manager_has_xdg_support(self): """Test that ResourceManager supports XDG directories.""" from vocalinux.utils.resource_manager import ResourceManager rm = ResourceManager() resources_dir = rm.resources_dir # Should be a valid path string assert isinstance(resources_dir, str), "resources_dir should be a string" assert len(resources_dir) > 0, "resources_dir should not be empty" class TestRecognitionManagerCrossDistro: """Test RecognitionManager cross-distro model path handling.""" def test_system_model_paths_exists(self): """Test that system model paths configuration exists.""" from vocalinux.speech_recognition.recognition_manager import SYSTEM_MODELS_DIRS # Should be a list of paths assert isinstance(SYSTEM_MODELS_DIRS, list), "SYSTEM_MODELS_DIRS should be a list" assert len(SYSTEM_MODELS_DIRS) > 0, "SYSTEM_MODELS_DIRS should not be empty" # Should include XDG paths has_xdg = any("/share/" in path for path in SYSTEM_MODELS_DIRS) assert has_xdg, "SYSTEM_MODELS_DIRS should include XDG paths" class TestDocumentation: """Test that documentation is accurate.""" def test_distro_compatibility_documentation_exists(self): """Test that DISTRO_COMPATIBILITY.md exists and is accurate.""" docs_path = REPO_ROOT / "docs" / "DISTRO_COMPATIBILITY.md" if not docs_path.exists(): pytest.skip(f"DISTRO_COMPATIBILITY.md not found at {docs_path}") content = docs_path.read_text() # Should mention the dynamic path detection assert ( "pkg-config" in content or "detect_typelib_path" in content ), "Should document dynamic path detection" # Should mention supported distros expected_distros = ["Ubuntu", "Debian", "Fedora", "Arch", "openSUSE"] for distro in expected_distros: assert distro in content, f"Should mention {distro} support" if __name__ == "__main__": pytest.main([__file__, "-v"])