| 1 | //! Compatibility policy facade over the adopted kit composer plan. |
| 2 | use crate::tui::app::ComposerDensity; |
| 3 | use codewhale_ratatui::{NativeComposerDensity, native_composer_height}; |
| 4 | fn density(value: ComposerDensity) -> NativeComposerDensity { |
| 5 | match value { |
| 6 | ComposerDensity::Compact => NativeComposerDensity::Compact, |
| 7 | ComposerDensity::Comfortable => NativeComposerDensity::Comfortable, |
| 8 | ComposerDensity::Spacious => NativeComposerDensity::Spacious, |
| 9 | } |
| 10 | } |
| 11 | #[cfg(test)] |
| 12 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
| 13 | pub struct ComposerChrome { |
| 14 | pub border_rows: u16, |
| 15 | pub max_total_rows: u16, |
| 16 | } |
| 17 | #[cfg(test)] |
| 18 | impl ComposerChrome { |
| 19 | pub fn for_density(value: ComposerDensity, panel: bool) -> Self { |
| 20 | Self { |
| 21 | border_rows: if panel { 2 } else { 1 }, |
| 22 | max_total_rows: density(value).max_rows(), |
| 23 | } |
| 24 | } |
| 25 | } |
| 26 | pub fn desired_height( |
| 27 | rows: usize, |
| 28 | menus: usize, |
| 29 | available: u16, |
| 30 | value: ComposerDensity, |
| 31 | panel: bool, |
| 32 | ) -> u16 { |
| 33 | native_composer_height(rows, menus, available, density(value), panel) |
| 34 | } |
| 35 | #[cfg(test)] |
| 36 | pub use codewhale_ratatui::native_composer_top_padding as top_padding; |
| 37 | #[cfg(test)] |
| 38 | #[path = "composer_chrome_legacy.rs"] |
| 39 | mod legacy; |
| 40 | #[cfg(test)] |
| 41 | pub use legacy::{render_tideline_composer_submit, tideline_composer_geometry}; |
| 42 | |
| 43 | #[cfg(test)] |
| 44 | mod tests { |
| 45 | use super::*; |
| 46 | |
| 47 | #[test] |
| 48 | fn short_composer_respects_density_and_keeps_padding_below_the_caret() { |
| 49 | for (density, height) in [ |
| 50 | (ComposerDensity::Compact, 2), |
| 51 | (ComposerDensity::Comfortable, 3), |
| 52 | (ComposerDensity::Spacious, 4), |
| 53 | ] { |
| 54 | assert_eq!(desired_height(1, 0, 8, density, false), height); |
| 55 | } |
| 56 | assert_eq!( |
| 57 | top_padding(1, 2), |
| 58 | 0, |
| 59 | "one spare row belongs below the input" |
| 60 | ); |
| 61 | assert_eq!(top_padding(1, 3), 1); |
| 62 | } |
| 63 | |
| 64 | #[test] |
| 65 | fn compact_height_sheds_border_before_content() { |
| 66 | // Only two rows available: keep a border + one content row. |
| 67 | let height = desired_height(1, 0, 2, ComposerDensity::Comfortable, false); |
| 68 | assert_eq!(height, 2); |
| 69 | } |
| 70 | |
| 71 | #[test] |
| 72 | fn content_growth_expands_up_to_the_density_cap() { |
| 73 | // Six content rows + border fits under the Comfortable cap of 9. |
| 74 | let height = desired_height(6, 0, 12, ComposerDensity::Comfortable, false); |
| 75 | assert_eq!(height, 7, "typed content must grow the composer: {height}"); |
| 76 | |
| 77 | // Past the cap the density setting wins, not the content. |
| 78 | let capped = desired_height(20, 0, 30, ComposerDensity::Comfortable, false); |
| 79 | assert_eq!(capped, 9, "Comfortable caps total rows at 9"); |
| 80 | let spacious = desired_height(20, 0, 30, ComposerDensity::Spacious, false); |
| 81 | assert_eq!(spacious, 12, "Spacious caps total rows at 12"); |
| 82 | } |
| 83 | |
| 84 | #[test] |
| 85 | fn spacious_panel_reserves_input_padding_and_both_borders() { |
| 86 | let height = desired_height(1, 0, 12, ComposerDensity::Spacious, true); |
| 87 | assert_eq!(height, 5, "panel = 2 borders + 3 input rows, got {height}"); |
| 88 | } |
| 89 | } |
| 90 |