import Adwaita import CAdw import CGtkWidgets import Testing // MARK: - Helpers /// Initialize GTK once per test suite. func ensureGTKInit() { struct Once { static let initialized: Bool = { gtk_init() return true }() } _ = Once.initialized } /// Create a simple test widget that reports a fixed size. func makeFixedChild(width: Int, height: Int) -> UnsafeMutablePointer? { let box = gtk_box_new(.GTK_ORIENTATION_VERTICAL, 0) gtk_widget_set_size_request(box, Int32(width), Int32(height)) gtk_widget_realize(box) return box } /// Measure a widget and return (minimum, natural). func measureWidget( _ widget: UnsafeMutablePointer?, orientation: GtkOrientation, forSize: Int = -1 ) -> (minimum: Int, natural: Int) { var min: Int32 = 0 var nat: Int32 = 0 gtk_widget_measure(widget, orientation, Int32(forSize), &min, &nat, nil, nil) return (Int(min), Int(nat)) } // MARK: - AspectContainer Tests @Suite("Widget Tests", .serialized) struct WidgetTests { init() { ensureGTKInit() } @Test("Reports height = width × ratio when for_size is known") func measureWithKnownWidth() { let container = aspect_container_new(2.0)! let child = makeFixedChild(width: 100, height: 50) gtk_widget_set_parent(child, container) let (minH, natH) = measureWidget( container, orientation: .GTK_ORIENTATION_VERTICAL, forSize: 100) #expect(minH == 200, "height = 100 × 2.0 = 200") #expect(natH == 200, "natural height = 200") } @Test("Reports height = child_min_w × ratio when for_size is unknown") func measureFallback() { let container = aspect_container_new(1.5)! let child = makeFixedChild(width: 100, height: 100) gtk_widget_set_parent(child, container) gtk_widget_set_size_request(container, 100, -1) let (minH, natH) = measureWidget( container, orientation: .GTK_ORIENTATION_VERTICAL, forSize: -1) #expect(minH == 150, "height = 100 × 1.5 = 150 (minimum)") #expect(natH == 150, "natural = 150") } @Test("max_width caps reported width") func maxWidthCapsWidth() { let container = aspect_container_new(1.5)! let child = makeFixedChild(width: 300, height: 300) gtk_widget_set_parent(child, container) aspect_container_set_max_width(container.opaque(), 200) let (minW, natW) = measureWidget( container, orientation: .GTK_ORIENTATION_HORIZONTAL, forSize: -1) #expect(minW == 200, "capped at 200") #expect(natW == 200, "capped at 200") } @Test("max_width affects height calculation") func maxWidthAffectsHeight() { let container = aspect_container_new(2.0)! let child = makeFixedChild(width: 300, height: 150) gtk_widget_set_parent(child, container) aspect_container_set_max_width(container.opaque(), 100) let (minH, natH) = measureWidget( container, orientation: .GTK_ORIENTATION_VERTICAL, forSize: -1) #expect(minH == 200, "height = max_width × ratio = 200") #expect(natH == 200, "natural = 200") } @Test("Changing aspect ratio triggers resize") func changeAspectRatio() { let container = aspect_container_new(1.0)! let child = makeFixedChild(width: 100, height: 100) gtk_widget_set_parent(child, container) aspect_container_set_aspect_ratio(container.opaque(), 0.5) let (minH, natH) = measureWidget( container, orientation: .GTK_ORIENTATION_VERTICAL, forSize: 100) #expect(minH == 50, "height = 100 × 0.5 = 50") #expect(natH == 50, "natural = 50") } @Test("Horizontal measure returns 0 without max_width") func horizontalMeasureNoMaxWidth() { let container = aspect_container_new(1.5)! let child = makeFixedChild(width: 300, height: 200) gtk_widget_set_parent(child, container) let (minW, natW) = measureWidget( container, orientation: .GTK_ORIENTATION_HORIZONTAL, forSize: -1) #expect(minW == 0, "no max_width → reports 0") #expect(natW == 0, "no max_width → reports 0") } // MARK: - AspectContainer Tests /// Helper: create a FlowGrid with `n` children, each having a given size. func makeFlowGrid( minimumSize: Int = 100, columnSpacing: Int = 0, rowSpacing: Int = 0, childSize: Int = 100, count: Int = 4 ) -> UnsafeMutablePointer? { let grid = flow_grid_new(Int32(minimumSize), Int32(columnSpacing), Int32(rowSpacing)) for _ in 0..