Add test target and widget unit tests
This commit is contained in:
parent
3a54e96d8b
commit
284a2c4842
2 changed files with 196 additions and 0 deletions
187
Tests/LuminateTests/WidgetTests.swift
Normal file
187
Tests/LuminateTests/WidgetTests.swift
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
import Adwaita
|
||||
import CAdw
|
||||
import CAspectContainer
|
||||
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<GtkWidget>? {
|
||||
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<GtkWidget>?,
|
||||
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<GtkWidget>? {
|
||||
let grid = flow_grid_new(Int32(minimumSize), Int32(columnSpacing), Int32(rowSpacing))
|
||||
for _ in 0..<count {
|
||||
let child = gtk_box_new(.GTK_ORIENTATION_VERTICAL, 0)
|
||||
gtk_widget_set_size_request(child, Int32(childSize), Int32(childSize))
|
||||
gtk_widget_set_parent(child, grid)
|
||||
}
|
||||
return grid
|
||||
}
|
||||
|
||||
@Test("Height = tallest child height when for_size is known")
|
||||
func measureTalliesRowHeights() {
|
||||
let grid = makeFlowGrid(
|
||||
minimumSize: 150, columnSpacing: 0, rowSpacing: 0, childSize: 100, count: 6)
|
||||
|
||||
let (minH, natH) = measureWidget(grid, orientation: .GTK_ORIENTATION_VERTICAL, forSize: 300)
|
||||
#expect(minH == 300, "3 rows × 100 = 300")
|
||||
#expect(natH == 300, "natural = 300")
|
||||
}
|
||||
|
||||
@Test("Column spacing is accounted for in column count")
|
||||
func columnSpacingAffectsCount() {
|
||||
let noSpacing = makeFlowGrid(
|
||||
minimumSize: 100, columnSpacing: 0, rowSpacing: 0, childSize: 100, count: 4)
|
||||
let withSpacing = makeFlowGrid(
|
||||
minimumSize: 100, columnSpacing: 50, rowSpacing: 0, childSize: 100, count: 4)
|
||||
|
||||
let (h1, _) = measureWidget(noSpacing, orientation: .GTK_ORIENTATION_VERTICAL, forSize: 250)
|
||||
#expect(h1 == 200, "250 width → 2 cols × 2 rows × 100 = 200")
|
||||
|
||||
let (h2, _) = measureWidget(
|
||||
withSpacing, orientation: .GTK_ORIENTATION_VERTICAL, forSize: 250)
|
||||
#expect(h2 == 200, "250 width → 2 cols × 2 rows × 100 = 200")
|
||||
}
|
||||
|
||||
@Test("Row spacing adds to total height")
|
||||
func rowSpacingAddsHeight() {
|
||||
let grid = makeFlowGrid(
|
||||
minimumSize: 100, columnSpacing: 0, rowSpacing: 10, childSize: 100, count: 6)
|
||||
|
||||
let (minH, natH) = measureWidget(grid, orientation: .GTK_ORIENTATION_VERTICAL, forSize: 300)
|
||||
#expect(minH == 210, "2 rows × 100 + 1 spacing × 10 = 210")
|
||||
#expect(natH == 210, "natural = 210")
|
||||
}
|
||||
|
||||
@Test("Single child fills one cell")
|
||||
func singleChild() {
|
||||
let grid = makeFlowGrid(minimumSize: 200, childSize: 150, count: 1)
|
||||
|
||||
let (minH, natH) = measureWidget(grid, orientation: .GTK_ORIENTATION_VERTICAL, forSize: 400)
|
||||
#expect(minH == 150, "single row = child height")
|
||||
#expect(natH == 150, "natural = 150")
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue