dissolve-python 0.3.0

A tool to dissolve deprecated calls in Python codebases
Documentation
// Test modules
#[cfg(test)]
mod test_ast_edge_cases;
#[cfg(test)]
mod test_ast_edge_cases_advanced;
#[cfg(test)]
mod test_ast_edge_cases_extended;
#[cfg(test)]
mod test_attribute_deprecation;
#[cfg(test)]
mod test_bug_fixes;
#[cfg(test)]
mod test_check;
#[cfg(test)]
mod test_class_methods;
#[cfg(test)]
mod test_class_wrapper_deprecation;
#[cfg(test)]
#[cfg(feature = "concurrent-lsp")]
mod test_concurrent_lsp;
#[cfg(test)]
mod test_coverage_improvements;
#[cfg(test)]
mod test_cross_module;
#[cfg(test)]
mod test_debug_magic_method;
#[cfg(test)]
mod test_dependency_inheritance;
#[cfg(test)]
mod test_dmypy_comparison;
#[cfg(test)]
mod test_dulwich_scenario;
#[cfg(test)]
mod test_edge_cases;
#[cfg(test)]
mod test_file_refresh;
#[cfg(test)]
mod test_formatting_preservation;
#[cfg(test)]
mod test_integration_commands;
#[cfg(test)]
mod test_interactive;
#[cfg(test)]
mod test_lazy_type_lookup;
#[cfg(test)]
mod test_magic_method_edge_cases;
#[cfg(test)]
mod test_magic_method_migration;
#[cfg(test)]
mod test_magic_methods_all;
#[cfg(test)]
mod test_migrate;
#[cfg(test)]
mod test_migration_issues;
#[cfg(test)]
mod test_readme_examples;
#[cfg(test)]
mod test_remove;
#[cfg(test)]
mod test_replace_me_corner_cases;
#[cfg(test)]
mod test_ruff_parser;
#[cfg(test)]
mod test_ruff_replacements;
#[cfg(test)]
mod test_type_introspection_failure;

#[cfg(test)]
pub mod test_utils {
    use std::fs;
    use tempfile::TempDir;

    /// Test context that manages temporary files
    pub struct TestContext {
        _temp_dir: TempDir,
        pub file_path: String,
    }

    impl TestContext {
        /// Create a new test context with a temporary Python file
        pub fn new(content: &str) -> Self {
            Self::new_with_module_name(content, "test_module")
        }

        /// Create a new test context with a specific module name
        pub fn new_with_module_name(content: &str, module_name: &str) -> Self {
            let temp_dir = TempDir::new().expect("Failed to create temp dir");
            let file_path = temp_dir.path().join(format!("{}.py", module_name));

            fs::write(&file_path, content).expect("Failed to write test file");

            TestContext {
                _temp_dir: temp_dir,
                file_path: file_path.to_string_lossy().to_string(),
            }
        }

        /// Get the workspace root (parent directory) for this test context
        pub fn workspace_root(&self) -> String {
            std::path::Path::new(&self.file_path)
                .parent()
                .unwrap()
                .to_string_lossy()
                .to_string()
        }

        /// Create a TypeIntrospectionContext with the correct workspace root for this test
        /// This creates a new client for each test to ensure proper cleanup
        pub fn create_type_context(
            &self,
            method: crate::types::TypeIntrospectionMethod,
        ) -> crate::type_introspection_context::TypeIntrospectionContext {
            // Create fresh client with workspace root for tests
            crate::type_introspection_context::TypeIntrospectionContext::new_with_workspace(
                method,
                Some(&self.workspace_root()),
            )
            .expect("Failed to create type introspection context")
        }
    }

    /// Create a TypeIntrospectionContext optimized for tests
    /// This creates a fresh client for each test to ensure proper cleanup
    pub fn create_test_type_context(
        method: crate::types::TypeIntrospectionMethod,
    ) -> crate::type_introspection_context::TypeIntrospectionContext {
        use crate::type_introspection_context::TypeIntrospectionContext;

        // Create a fresh client for tests to ensure proper cleanup
        TypeIntrospectionContext::new_with_workspace(method, None)
            .expect("Failed to create type introspection context for tests")
    }

    /// Create a TypeIntrospectionContext with a specific workspace root for tests
    /// This ensures LSP clients use the correct workspace for type introspection
    pub fn create_test_type_context_with_workspace(
        method: crate::types::TypeIntrospectionMethod,
        workspace_root: &str,
    ) -> crate::type_introspection_context::TypeIntrospectionContext {
        use crate::type_introspection_context::TypeIntrospectionContext;

        // Create a fresh client for tests to ensure proper cleanup
        TypeIntrospectionContext::new_with_workspace(method, Some(workspace_root))
            .expect("Failed to create type introspection context with workspace for tests")
    }
}