// SPDX-License-Identifier: LGPL-2.1-only // Copyright (C) 2026 Liberux Labs, S. L. use super::*; use crate::layout::spacer::spacer; #[ derive( Clone, Debug, PartialEq, Eq ) ] enum Msg { Cancel, Dismiss } #[ test ] fn new_defaults_are_modal_with_no_content() { let d = Dialog::::new(); assert!( d.modal ); assert!( d.title.is_none() ); assert!( d.subtitle.is_none() ); assert!( d.body.is_none() ); assert!( d.actions.is_empty() ); assert!( d.dismiss_msg.is_none() ); assert!( d.cancel_msg.is_none() ); assert_eq!( d.max_width, crate::types::Length::fluid( DEFAULT_MAX_WIDTH ) ); } #[ test ] fn title_and_subtitle_builders_set_strings() { let d = Dialog::::new() .title( "Hello" ) .subtitle( "World" ); assert_eq!( d.title.as_deref(), Some( "Hello" ) ); assert_eq!( d.subtitle.as_deref(), Some( "World" ) ); } #[ test ] fn body_builder_replaces_existing_body() { let d = Dialog::::new() .body( spacer() ) .body( spacer() ); assert!( d.body.is_some() ); } #[ test ] fn action_builder_appends_in_order() { let d = Dialog::::new() .action( spacer() ) .action( spacer() ) .action( spacer() ); assert_eq!( d.actions.len(), 3 ); } #[ test ] fn modal_builder_toggles_flag() { assert!( !Dialog::::new().modal( false ).modal ); assert!( Dialog::::new().modal( true ).modal ); } #[ test ] fn dismiss_on_scrim_builder_records_message() { let d = Dialog::::new() .modal( false ) .dismiss_on_scrim( Msg::Dismiss ); assert_eq!( d.dismiss_msg, Some( Msg::Dismiss ) ); } #[ test ] fn cancel_builder_records_escape_message() { let d = Dialog::::new().cancel( Msg::Cancel ); assert_eq!( d.cancel_msg, Some( Msg::Cancel ) ); } #[ test ] fn max_width_builder_overrides_default() { let d = Dialog::::new().max_width( 720.0 ); assert_eq!( d.max_width, crate::types::Length::px( 720.0 ) ); } #[ test ] #[ should_panic( expected = "dismiss_on_scrim is not valid when modal=true" ) ] fn modal_with_dismiss_panics_at_lower() { // Construction allows the combination; only the lowering // to `Element` enforces the contract — that is where the // invariant matters because that is where input dispatch // would have to honour two contradictory rules. let d = Dialog::::new() .modal( true ) .dismiss_on_scrim( Msg::Dismiss ); let _: Element = d.into(); } #[ test ] fn non_modal_with_dismiss_lowers_cleanly() { let d = Dialog::::new() .modal( false ) .dismiss_on_scrim( Msg::Dismiss ) .cancel( Msg::Cancel ) .title( "Title" ); // Lowering must not panic. let _: Element = d.into(); } #[ test ] fn modal_with_cancel_only_lowers_cleanly() { // modal=true + cancel(...) (no dismiss_on_scrim) is the // canonical confirm-dialog shape. let d = Dialog::::new() .title( "Confirm" ) .subtitle( "Are you sure?" ) .cancel( Msg::Cancel ); let _: Element = d.into(); }