winrt-xaml 1.0.0

A Rust library for creating modern Windows UIs using WinRT and XAML with reactive data binding
Documentation
//! Unit tests for application management.
//!
//! Note: These tests use a global singleton (Application), so they test
//! the existing application instance if one exists.

use winrt_xaml::app::Application;
use winrt_xaml::error::Error;

#[test]
fn test_application_singleton() {
    // Try to create an application
    let app1 = Application::new();

    // If it succeeds, try to create another (should fail)
    if app1.is_ok() {
        let app2 = Application::new();
        assert!(app2.is_err());

        // Verify error message
        match app2 {
            Err(e) => {
                let msg = e.to_string();
                assert!(msg.contains("Application already created") || msg.contains("application"));
            }
            Ok(_) => panic!("Expected error for duplicate application"),
        }
    }
    // If it fails, that's also fine (application already exists from another test)
}

#[test]
fn test_application_current() {
    // Get or create an application
    let app = Application::current().or_else(|| Application::new().ok());

    if let Some(app) = app {
        // Current should return the same application
        let current = Application::current();
        assert!(current.is_some());

        // Just verify they refer to the same instance
        let current = Application::current().unwrap();
        assert_eq!(app.exit_code(), current.exit_code());
    }
}

#[test]
fn test_application_exit_code() {
    let app = Application::current().or_else(|| Application::new().ok());

    if let Some(app) = app {
        // Just test that exit_code() method exists and returns a value
        let code = app.exit_code();
        assert!(code >= 0 || code < 0); // Always true, just tests the method works
    }
}

#[test]
fn test_application_should_exit() {
    let app = Application::current().or_else(|| Application::new().ok());

    if let Some(app) = app {
        // Just test that should_exit() method exists and returns a bool
        let _ = app.should_exit();
        // Don't modify global state
    }
}

#[test]
fn test_application_exit_with_code() {
    let app = Application::current().or_else(|| Application::new().ok());

    if let Some(app) = app {
        // Just test that the methods exist and work
        let _ = app.exit_code();
        // Don't modify global state in parallel tests
    }
}

#[test]
fn test_application_exit() {
    let app = Application::current().or_else(|| Application::new().ok());

    if let Some(app) = app {
        // Just test that exit() method exists
        let _ = app.exit_code();
        // Don't call exit() as it affects all tests
    }
}

#[test]
fn test_application_clone() {
    let app1 = Application::current().or_else(|| Application::new().ok());

    if let Some(app1) = app1 {
        let app2 = app1.clone();

        // Both should refer to the same application
        // Test that they have the same exit code
        assert_eq!(app1.exit_code(), app2.exit_code());
    }
}

#[test]
fn test_application_state_sharing() {
    let app1 = Application::current().or_else(|| Application::new().ok());

    if let Some(app1) = app1 {
        let app2 = app1.clone();
        let initial_code = app1.exit_code();

        // Modify state through app1
        app1.exit_with_code(77);

        // State should be visible through app2
        assert_eq!(app2.exit_code(), 77);

        // Modify through app2
        app2.exit_with_code(88);

        // Should be visible through app1
        assert_eq!(app1.exit_code(), 88);

        // Restore
        app1.exit_with_code(initial_code);
    }
}

#[test]
fn test_application_current_before_creation() {
    // Before any application is created, current() should return None
    // Note: This test might fail if run after other tests that create an application
    // In a real test suite, we'd need test isolation

    // We can't actually test this properly due to the global singleton,
    // but we can verify the API exists
    let _current = Application::current();
}

#[test]
fn test_error_application_type() {
    let err = Error::application("Test application error");
    let msg = err.to_string();
    assert!(msg.contains("Application error") || msg.contains("Test application error"));
}

// Note: We can't easily test run() because it blocks waiting for messages
// and requires a real window message loop. Integration tests would be better for that.

#[test]
fn test_application_api_exists() {
    // Compile-time checks that the API exists

    fn _check_new() {
        fn _needs_result<T>(_: fn() -> Result<T, Error>) {}
        _needs_result(Application::new);
    }

    fn _check_current() {
        fn _needs_option<T>(_: fn() -> Option<T>) {}
        _needs_option(Application::current);
    }

    fn _check_exit() {
        fn _needs_method(_: fn(&Application)) {}
        _needs_method(Application::exit);
    }

    fn _check_exit_with_code() {
        fn _needs_method(_: fn(&Application, i32)) {}
        _needs_method(Application::exit_with_code);
    }

    fn _check_exit_code() {
        fn _needs_method(_: fn(&Application) -> i32) {}
        _needs_method(Application::exit_code);
    }

    fn _check_should_exit() {
        fn _needs_method(_: fn(&Application) -> bool) {}
        _needs_method(Application::should_exit);
    }
}