168 lines
5.3 KiB
Swift
168 lines
5.3 KiB
Swift
import Testing
|
|
@_spi(SGTKInternal) import Gtk
|
|
@_spi(Portico) import Portico
|
|
|
|
@MainActor @Suite(.serialized) struct ConditionalTests {
|
|
|
|
// MARK: - EitherView
|
|
|
|
@Test func eitherViewInitiallyTrueBranch() {
|
|
guard Gtk.initCheck() else { return }
|
|
ConditionProbe.reset()
|
|
|
|
let box = StateBox(true)
|
|
let binding = Binding(box)
|
|
let view = EitherView(binding,
|
|
first: { FirstProbeLabel() },
|
|
second: { SecondProbeLabel() }
|
|
)
|
|
let widget = AnyView(view).makeWidget(MountContext())
|
|
let stack = widget as! Gtk.Stack
|
|
|
|
// Initially, only the "true" branch is mounted and visible.
|
|
#expect(stack.getVisibleChildName() == "true")
|
|
#expect(ConditionProbe.firstCount == 1)
|
|
#expect(ConditionProbe.secondCount == 0)
|
|
|
|
// Toggle to false — lazy-mounts the "false" branch.
|
|
box.set(false)
|
|
#expect(stack.getVisibleChildName() == "false")
|
|
#expect(ConditionProbe.firstCount == 1)
|
|
#expect(ConditionProbe.secondCount == 1)
|
|
|
|
// Toggle back to true — no new mounts.
|
|
box.set(true)
|
|
#expect(stack.getVisibleChildName() == "true")
|
|
#expect(ConditionProbe.firstCount == 1)
|
|
#expect(ConditionProbe.secondCount == 1)
|
|
}
|
|
|
|
@Test func eitherViewInitiallyFalseBranch() {
|
|
guard Gtk.initCheck() else { return }
|
|
ConditionProbe.reset()
|
|
|
|
let box = StateBox(false)
|
|
let binding = Binding(box)
|
|
let view = EitherView(binding,
|
|
first: { FirstProbeLabel() },
|
|
second: { SecondProbeLabel() }
|
|
)
|
|
let widget = AnyView(view).makeWidget(MountContext())
|
|
let stack = widget as! Gtk.Stack
|
|
|
|
// Initially, only the "false" branch is mounted and visible.
|
|
#expect(stack.getVisibleChildName() == "false")
|
|
#expect(ConditionProbe.firstCount == 0)
|
|
#expect(ConditionProbe.secondCount == 1)
|
|
|
|
// Toggle to true — lazy-mounts the "true" branch.
|
|
box.set(true)
|
|
#expect(stack.getVisibleChildName() == "true")
|
|
#expect(ConditionProbe.firstCount == 1)
|
|
#expect(ConditionProbe.secondCount == 1)
|
|
|
|
// Toggle back to false — no new mounts.
|
|
box.set(false)
|
|
#expect(stack.getVisibleChildName() == "false")
|
|
#expect(ConditionProbe.firstCount == 1)
|
|
#expect(ConditionProbe.secondCount == 1)
|
|
}
|
|
|
|
@Test func eitherViewTracksConditionChanges() {
|
|
guard Gtk.initCheck() else { return }
|
|
ConditionProbe.reset()
|
|
|
|
let box = StateBox(true)
|
|
let binding = Binding(box)
|
|
let view = EitherView(binding,
|
|
first: { FirstProbeLabel() },
|
|
second: { SecondProbeLabel() }
|
|
)
|
|
let widget = AnyView(view).makeWidget(MountContext())
|
|
let stack = widget as! Gtk.Stack
|
|
|
|
// Three toggles: true→false→true→false
|
|
box.set(false)
|
|
box.set(true)
|
|
box.set(false)
|
|
|
|
#expect(stack.getVisibleChildName() == "false")
|
|
#expect(ConditionProbe.firstCount == 1)
|
|
#expect(ConditionProbe.secondCount == 1)
|
|
}
|
|
|
|
// MARK: - OptionalView
|
|
|
|
@Test func optionalViewMountsChildOnce() {
|
|
guard Gtk.initCheck() else { return }
|
|
ConditionProbe.reset()
|
|
|
|
let box = StateBox(true)
|
|
let binding = Binding(box)
|
|
let view = OptionalView(binding) { FirstProbeLabel() }
|
|
let widget = AnyView(view).makeWidget(MountContext())
|
|
let revealer = widget as! Gtk.Revealer
|
|
|
|
// Initially revealed, child mounted once.
|
|
#expect(revealer.getRevealChild() == true)
|
|
#expect(ConditionProbe.firstCount == 1)
|
|
|
|
// Toggle to false — child still mounted, just hidden.
|
|
box.set(false)
|
|
#expect(revealer.getRevealChild() == false)
|
|
#expect(ConditionProbe.firstCount == 1)
|
|
|
|
// Toggle back to true — still same child.
|
|
box.set(true)
|
|
#expect(revealer.getRevealChild() == true)
|
|
#expect(ConditionProbe.firstCount == 1)
|
|
}
|
|
|
|
@Test func optionalViewHidesWhenConditionFalse() {
|
|
guard Gtk.initCheck() else { return }
|
|
ConditionProbe.reset()
|
|
|
|
let box = StateBox(false)
|
|
let binding = Binding(box)
|
|
let view = OptionalView(binding) { FirstProbeLabel() }
|
|
let widget = AnyView(view).makeWidget(MountContext())
|
|
let revealer = widget as! Gtk.Revealer
|
|
|
|
// Initially hidden, but child WAS mounted (build-once).
|
|
#expect(revealer.getRevealChild() == false)
|
|
#expect(ConditionProbe.firstCount == 1)
|
|
|
|
// Toggle to true — child visible, no remount.
|
|
box.set(true)
|
|
#expect(revealer.getRevealChild() == true)
|
|
#expect(ConditionProbe.firstCount == 1)
|
|
}
|
|
}
|
|
|
|
// MARK: - Test helpers
|
|
|
|
@MainActor fileprivate enum ConditionProbe {
|
|
static var firstCount = 0
|
|
static var secondCount = 0
|
|
|
|
static func reset() {
|
|
firstCount = 0
|
|
secondCount = 0
|
|
}
|
|
}
|
|
|
|
@MainActor fileprivate struct FirstProbeLabel: View, Mountable {
|
|
var body: Never { fatalError() }
|
|
func mount(_ ctx: MountContext) -> Gtk.Widget {
|
|
ConditionProbe.firstCount += 1
|
|
return Gtk.Label(str: "first")
|
|
}
|
|
}
|
|
|
|
@MainActor fileprivate struct SecondProbeLabel: View, Mountable {
|
|
var body: Never { fatalError() }
|
|
func mount(_ ctx: MountContext) -> Gtk.Widget {
|
|
ConditionProbe.secondCount += 1
|
|
return Gtk.Label(str: "second")
|
|
}
|
|
}
|