Files
conjure/Tests/ConjureKitTests/ActionsBackgroundTests.swift
T

89 lines
4.6 KiB
Swift

import AppKit
import ConjureKit
import Testing
@testable import Conjure
@Test @MainActor func popupBackgroundMatchesWindowGradientAcrossTransitions() throws {
_ = NSApplication.shared
let window = NSWindow(contentRect: NSRect(x: 0, y: 0, width: 750, height: 480),
styleMask: .borderless, backing: .buffered, defer: false)
window.isReleasedWhenClosed = false
let host = try #require(window.contentView)
let reference = LauncherBackground(frame: host.bounds)
host.addSubview(reference)
let footer = NSView(frame: NSRect(x: 500, y: 8, width: 230, height: 36))
let header = NSView(frame: NSRect(x: 500, y: 420, width: 230, height: 36))
let actionButton = NSButton(frame: footer.bounds)
let providerButton = NSButton(frame: header.bounds)
footer.addSubview(actionButton)
header.addSubview(providerButton)
host.addSubview(footer)
host.addSubview(header)
let actions = ApplicationActionsController()
defer { actions.close(animated: false); window.orderOut(nil) }
func descendants(_ view: NSView) -> [NSView] { [view] + view.subviews.flatMap(descendants) }
func snapshot(_ view: NSView) throws -> NSBitmapImageRep {
let bitmap = try #require(view.bitmapImageRepForCachingDisplay(in: view.bounds))
view.cacheDisplay(in: view.bounds, to: bitmap)
return bitmap
}
func color(_ bitmap: NSBitmapImageRep, at point: NSPoint, in view: NSView) throws -> NSColor {
let x = Int(point.x * CGFloat(bitmap.pixelsWide) / view.bounds.width)
let y = bitmap.pixelsHigh - 1 - Int(point.y * CGFloat(bitmap.pixelsHigh) / view.bounds.height)
return try #require(bitmap.colorAt(x: x, y: y)?.usingColorSpace(.deviceRGB))
}
for animatedClose in [false, true] {
actions.showTranslation(relativeTo: actionButton)
actions.close(animated: animatedClose)
actions.showProviders(selectedOpenAI: true, relativeTo: providerButton)
let background = try #require(descendants(actions.view).compactMap { $0 as? LauncherBackground }.first)
let actual = try snapshot(background)
let expected = try snapshot(reference)
// Sample the title strip and the body, away from text and selection rows.
for y in [background.bounds.height - 8, background.bounds.height / 2, 8] {
let point = NSPoint(x: 8, y: y)
let actualColor = try color(actual, at: point, in: background)
let expectedColor = try color(expected, at: background.convert(point, to: reference), in: reference)
#expect(abs(actualColor.redComponent - expectedColor.redComponent) < 0.02)
#expect(abs(actualColor.greenComponent - expectedColor.greenComponent) < 0.02)
#expect(abs(actualColor.blueComponent - expectedColor.blueComponent) < 0.02)
#expect(abs(actualColor.alphaComponent - expectedColor.alphaComponent) < 0.02)
}
actions.close(animated: false)
}
}
@Test @MainActor func providerPickerReplacesAnchorDownwardAndKeepsCurrentSelection() throws {
_ = NSApplication.shared
let window = NSWindow(contentRect: NSRect(x: 0, y: 0, width: 750, height: 480),
styleMask: .borderless, backing: .buffered, defer: false)
window.isReleasedWhenClosed = false
let host = try #require(window.contentView)
let pill = NSView(frame: NSRect(x: 500, y: 420, width: 230, height: 36))
let anchor = NSButton(frame: pill.bounds)
pill.addSubview(anchor)
host.addSubview(pill)
let popup = ApplicationActionsController()
defer { popup.close(animated: false); window.orderOut(nil) }
var selections: [Bool] = []
popup.selectProvider = { selections.append($0) }
popup.showProviders(selectedOpenAI: true, relativeTo: anchor)
let rect = popup.view.convert(popup.view.bounds, to: host)
#expect(rect.maxY == pill.frame.maxY)
#expect(rect.minY < pill.frame.minY)
#expect(rect.maxX == pill.frame.maxX)
#expect(pill.isAccessibilityHidden())
_ = popup.handle(#selector(NSResponder.insertNewline(_:)))
#expect(selections == [true])
// Reopen during the close animation, then switch modes without retaining the old anchor.
popup.showTranslation(relativeTo: anchor)
popup.showProviders(selectedOpenAI: false, relativeTo: anchor)
#expect(popup.view.convert(popup.view.bounds, to: host).maxY == pill.frame.maxY)
popup.moveSelection(by: 1)
_ = popup.handle(#selector(NSResponder.insertNewline(_:)))
#expect(selections == [true, true])
popup.close(animated: false)
#expect(pill.alphaValue == 1)
#expect(!pill.isAccessibilityHidden())
}