102 lines
4.2 KiB
Swift
102 lines
4.2 KiB
Swift
import Testing
|
|
@_spi(SGTKInternal) import Gtk
|
|
@_spi(SGTKInternal) import Adw
|
|
@_spi(Portico) import Portico
|
|
|
|
@MainActor @Suite(.serialized) struct WidgetRefTests {
|
|
@Test func backwardReference() {
|
|
guard Gtk.initCheck() else { return }
|
|
let ref = WidgetRef<Adw.Carousel>()
|
|
let context = MountContext()
|
|
let root = AnyView(VStack {
|
|
Carousel { Label(str: "a") }.ref(ref)
|
|
CarouselIndicatorDots().carousel(ref.projectedValue)
|
|
}).makeWidget(context) as! Gtk.Box
|
|
let first = root.getFirstChild()!
|
|
let carousel = Adw.Carousel(retaining: first.pointer)
|
|
let dots = Adw.CarouselIndicatorDots(retaining: first.getNextSibling()!.pointer)
|
|
#expect(dots.getCarousel()?.pointer == carousel.pointer)
|
|
}
|
|
|
|
@Test func forwardReference() {
|
|
guard Gtk.initCheck() else { return }
|
|
let ref = WidgetRef<Adw.Carousel>()
|
|
let context = MountContext()
|
|
let root = AnyView(VStack {
|
|
CarouselIndicatorDots().carousel(ref.projectedValue)
|
|
Carousel { Label(str: "a") }.ref(ref)
|
|
}).makeWidget(context) as! Gtk.Box
|
|
let first = root.getFirstChild()!
|
|
let dots = Adw.CarouselIndicatorDots(retaining: first.pointer)
|
|
let carousel = Adw.Carousel(retaining: first.getNextSibling()!.pointer)
|
|
#expect(dots.getCarousel()?.pointer == carousel.pointer)
|
|
}
|
|
|
|
@Test func latePublishFromForEach() {
|
|
guard Gtk.initCheck() else { return }
|
|
let ref = WidgetRef<Adw.Carousel>()
|
|
let items = StateBox<[Int]>([])
|
|
let context = MountContext()
|
|
let root = AnyView(VStack {
|
|
CarouselIndicatorDots().carousel(ref.projectedValue)
|
|
ForEach(Binding(items), id: \.self) { _ in Carousel().ref(ref) }
|
|
}).makeWidget(context) as! Gtk.Box
|
|
let first = root.getFirstChild()!
|
|
let dots = Adw.CarouselIndicatorDots(retaining: first.pointer)
|
|
#expect(dots.getCarousel() == nil)
|
|
items.set([1])
|
|
let carousel = Adw.Carousel(retaining: first.getNextSibling()!.pointer)
|
|
#expect(dots.getCarousel()?.pointer == carousel.pointer)
|
|
}
|
|
|
|
@Test func teardownClearsPublishedWidget() {
|
|
guard Gtk.initCheck() else { return }
|
|
let ref = WidgetRef<Adw.Carousel>()
|
|
let items = StateBox<[Int]>([])
|
|
let ctx = MountContext()
|
|
_ = AnyView(VStack {
|
|
CarouselIndicatorDots().carousel(ref.projectedValue)
|
|
ForEach(Binding(items), id: \.self) { _ in
|
|
Carousel().ref(ref)
|
|
}
|
|
}).makeWidget(ctx)
|
|
|
|
items.set([1])
|
|
#expect(ref.wrappedValue != nil)
|
|
ctx.registry.teardown()
|
|
#expect(ref.wrappedValue == nil)
|
|
}
|
|
|
|
/// A `WidgetRef` declared at the concrete subclass feeds a modifier whose property
|
|
/// is declared `Gtk.Widget?`; the generated overload is generic, so `Binding`'s
|
|
/// invariance does not reject it.
|
|
/// A `WidgetRef` declared at the concrete subclass feeds a modifier whose property
|
|
/// is declared `Gtk.Widget?`; the generated overload is generic.
|
|
@Test func widgetTypedBindingOverload() {
|
|
guard Gtk.initCheck() else { return }
|
|
let entryRef = WidgetRef<Gtk.Entry>()
|
|
let context = MountContext()
|
|
let root = AnyView(VStack {
|
|
Entry().ref(entryRef)
|
|
Label(str: "N").mnemonicWidget(entryRef.projectedValue)
|
|
}).makeWidget(context) as! Gtk.Box
|
|
let first = root.getFirstChild()!
|
|
let entry = Gtk.Entry(retaining: first.pointer)
|
|
let label = Gtk.Label(retaining: first.getNextSibling()!.pointer)
|
|
#expect(label.getMnemonicWidget()?.pointer == entry.pointer)
|
|
}
|
|
|
|
@Test func loweredNullableBindingOverload() {
|
|
guard Gtk.initCheck() else { return }
|
|
let stackRef = WidgetRef<Gtk.Stack>()
|
|
let root = AnyView(VStack {
|
|
Stack().ref(stackRef)
|
|
StackSidebar().stack(stackRef.projectedValue)
|
|
}).makeWidget(MountContext()) as! Gtk.Box
|
|
|
|
let first = root.getFirstChild()!
|
|
let stack = Gtk.Stack(retaining: first.pointer)
|
|
let sidebar = Gtk.StackSidebar(retaining: first.getNextSibling()!.pointer)
|
|
#expect(sidebar.getStack()?.pointer == stack.pointer)
|
|
}
|
|
}
|