Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions crates/coldvox-text-injection/src/tests/mock_harness.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@

use async_trait::async_trait;
use std::fs;
use std::io::Write;
use std::path::PathBuf;
use tempfile::NamedTempFile;

use crate::{InjectionContext, InjectionResult, TextInjector};

// A mock TextInjector that writes to a temporary file instead of a real UI element.
pub struct MockTextInjector;

#[async_trait]
impl TextInjector for MockTextInjector {
async fn inject_text(&self, text: &str, context: Option<&InjectionContext>) -> InjectionResult<()> {
let output_file = context
.and_then(|c| c.test_harness_output_file.as_ref())
.expect("MockTextInjector requires a test_harness_output_file in the context");

let mut file = fs::OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(output_file)?;

file.write_all(text.as_bytes())?;
Ok(())
}

async fn is_available(&self) -> bool {
true
}

fn backend_name(&self) -> &'static str {
"mock"
}

fn backend_info(&self) -> Vec<(&'static str, String)> {
vec![]
}
}

// Manages the lifecycle of a mock application's resources (e.g., a temp file).
pub struct MockTestApp {
pub output_file: PathBuf,
// Keep the temp file handle to ensure it's deleted on drop
_temp_file: NamedTempFile,
}

impl MockTestApp {
// Creates a new mock application instance.
pub fn new() -> Self {
let temp_file = NamedTempFile::new().expect("Failed to create temp file for mock app");
Self {
output_file: temp_file.path().to_path_buf(),
_temp_file: temp_file,
}
}
}

// A factory for creating MockTestApp instances.
pub struct MockTestAppManager;

impl MockTestAppManager {
// "Launches" a new mock application.
pub fn launch_mock_app() -> MockTestApp {
MockTestApp::new()
}
}
61 changes: 61 additions & 0 deletions crates/coldvox-text-injection/src/tests/mock_injection.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@

use crate::tests::mock_harness::{MockTestAppManager, MockTextInjector};
use crate::tests::test_harness::verify_injection;
use crate::{InjectionContext, TextInjector};

// Helper function to run a complete mock injection and verification test.
async fn run_mock_injection_test(test_text: &str) {
// 1. "Launch" the mock application. This creates a temporary file.
let app = MockTestAppManager::launch_mock_app();

// 2. Create the mock injector and the injection context.
let injector = MockTextInjector;
let context = InjectionContext {
test_harness_output_file: Some(app.output_file.clone()),
..Default::default()
};

// 3. Perform the injection. This writes the text to the temp file.
injector
.inject_text(test_text, Some(&context))
.await
.expect("Mock injection failed");

// 4. Verify the content of the temporary file.
verify_injection(&app.output_file, test_text)
.await
.unwrap_or_else(|e| {
panic!(
"Verification failed for mock injection with text '{}': {}",
test_text, e
)
});
}

#[tokio::test]
async fn test_mock_simple_text_injection() {
run_mock_injection_test("Hello from the mock injector!").await;
}

#[tokio::test]
async fn test_mock_unicode_text_injection() {
run_mock_injection_test("Hello ColdVox 🎤 mock test").await;
}

#[tokio::test]
async fn test_mock_long_text_injection() {
let long_text =
"This is a long string designed to test the mock injection capabilities. ".repeat(50);
assert!(long_text.len() > 1000);
run_mock_injection_test(&long_text).await;
}

#[tokio::test]
async fn test_mock_special_chars_injection() {
run_mock_injection_test("Line 1\nLine 2\twith a tab\nAnd symbols: !@#$%^&*()_+").await;
}

#[tokio::test]
async fn test_mock_empty_string_injection() {
run_mock_injection_test("").await;
}
16 changes: 15 additions & 1 deletion crates/coldvox-text-injection/src/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
//! Test modules for coldvox-text-injection

// pub mod real_injection;
// Integration tests requiring a live display server and user interaction.
// Gated by the `real-injection-tests` feature.
#[cfg(feature = "real-injection-tests")]
pub mod real_injection;

// Mock harness for headless unit testing of injection logic.
pub mod mock_harness;

// Unit tests using the mock harness.
pub mod mock_injection;

// Shared test utilities and application runners.
pub mod test_harness;
pub mod test_utils;

// Specific backend tests (wl-copy, etc.)
pub mod wl_copy_basic_test;
pub mod wl_copy_simple_test;
pub mod wl_copy_stdin_test;
Loading