native macOS codings agent orchestrator prowl.onev.cat
Something went wrong. Try again.
Swift
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358import CoreGraphicsimport Testing
@testable import Prowl
@MainActorstruct AgentIslandScreenTests { @Test func explicitDisplayWinsOverAutomaticCandidates() throws { let builtIn = screen(id: "built-in", isBuiltIn: true, hasNotch: true) let external = screen(id: "external", origin: CGPoint(x: -1_920, y: 0))
let resolved = AgentIslandScreenLayout.resolve( preference: .display(id: external.id, name: external.name), screens: [builtIn, external], mainWindowScreenID: builtIn.id, mainScreenID: builtIn.id )
#expect(try #require(resolved).id == external.id) }
@Test func disconnectedDisplayTemporarilyFallsBackToAutomatic() throws { let builtIn = screen(id: "built-in", isBuiltIn: true, hasNotch: true) let mainWindow = screen(id: "main-window")
let resolved = AgentIslandScreenLayout.resolve( preference: .display(id: "disconnected", name: "Studio Display"), screens: [builtIn, mainWindow], mainWindowScreenID: mainWindow.id, mainScreenID: builtIn.id )
#expect(try #require(resolved).id == mainWindow.id) }
@Test func automaticFallsBackThroughMainWindowBuiltInNotchAndMainScreen() throws { let mainWindow = screen(id: "main-window") let builtIn = screen(id: "built-in", isBuiltIn: true, hasNotch: true) let systemMain = screen(id: "system-main")
let windowResolved = AgentIslandScreenLayout.resolve( preference: .automatic, screens: [systemMain, builtIn, mainWindow], mainWindowScreenID: mainWindow.id, mainScreenID: systemMain.id ) #expect(try #require(windowResolved).id == mainWindow.id)
let notchResolved = AgentIslandScreenLayout.resolve( preference: .automatic, screens: [systemMain, builtIn], mainWindowScreenID: nil, mainScreenID: systemMain.id ) #expect(try #require(notchResolved).id == builtIn.id)
let mainResolved = AgentIslandScreenLayout.resolve( preference: .automatic, screens: [mainWindow, systemMain], mainWindowScreenID: nil, mainScreenID: systemMain.id ) #expect(try #require(mainResolved).id == systemMain.id) }
@Test func notchedPanelPinsToPhysicalTopEdge() { let display = screen( id: "notched", origin: CGPoint(x: 0, y: 240), isBuiltIn: true, hasNotch: true )
let frame = AgentIslandScreenLayout.panelFrame( contentSize: CGSize(width: 420, height: 180), screen: display, floatingHorizontalPosition: 0.1 )
#expect(frame.midX == display.notchFrame?.midX) #expect(frame.maxY == display.frame.maxY) }
@Test func notchFrameUsesAuxiliaryAreasAsContentExclusionZone() throws { let frame = CGRect(x: 0, y: 0, width: 1_512, height: 982)
let notchFrame = AgentIslandScreenLayout.notchFrame( screenFrame: frame, safeAreaTopInset: 32, auxiliaryTopLeftArea: CGRect(x: 0, y: 950, width: 663, height: 32), auxiliaryTopRightArea: CGRect(x: 848, y: 950, width: 664, height: 32) )
#expect(try #require(notchFrame) == CGRect(x: 663, y: 950, width: 185, height: 32)) }
@Test func notchedCompactLayoutReservesThePhysicalCutout() { let layout = AgentIslandNotchLayout(cutoutSize: CGSize(width: 185, height: 32))
// Each wing holds three 20pt icons (70pt) plus the chevron slot and insets. #expect(layout.compactWidth == 381) #expect(layout.compactHeight == 32) #expect(layout.wingWidth == 98) #expect((layout.wingWidth * 2) + layout.cutoutSize.width == layout.compactWidth) }
@Test func notchedWingsDoNotGrowWithANarrowCutout() { let layout = AgentIslandNotchLayout(cutoutSize: CGSize(width: 150, height: 32))
#expect(layout.wingWidth == 98) #expect(layout.compactWidth == 346) }
@Test func notchedCompactHeightFollowsTheCutoutWithAFloorForTheIconCluster() { // "More Space" scaling reports a shorter inset; "Larger Text" a taller one. Both stay flush. #expect(AgentIslandNotchLayout(cutoutSize: CGSize(width: 165, height: 27)).compactHeight == 28) #expect(AgentIslandNotchLayout(cutoutSize: CGSize(width: 185, height: 32)).compactHeight == 32) #expect(AgentIslandNotchLayout(cutoutSize: CGSize(width: 208, height: 36)).compactHeight == 36) }
@Test func floatingPillOverlaysTheMenuBarAndSupportsNegativeCoordinates() { let display = screen( id: "external", origin: CGPoint(x: -2_560, y: -180), visibleTopInset: 32 )
let frame = AgentIslandScreenLayout.panelFrame( contentSize: CGSize(width: 420, height: 200), screen: display )
#expect(frame.midX == display.frame.midX) #expect(frame.maxY == display.frame.maxY) #expect(display.menuBarHeight == 32) }
@Test func floatingPillUsesTheStoredHorizontalPosition() { let display = screen(id: "external")
let frame = AgentIslandScreenLayout.panelFrame( contentSize: CGSize(width: 300, height: 40), screen: display, floatingHorizontalPosition: 0.25 )
#expect(frame.midX == 480) }
@Test func floatingPillStaysInsideTheVisibleHorizontalBounds() { let display = screen(id: "external")
let leadingFrame = AgentIslandScreenLayout.panelFrame( contentSize: CGSize(width: 420, height: 200), screen: display, floatingHorizontalPosition: 0 ) let trailingFrame = AgentIslandScreenLayout.panelFrame( contentSize: CGSize(width: 420, height: 200), screen: display, floatingHorizontalPosition: 1 )
#expect( leadingFrame.minX == display.visibleFrame.minX + AgentIslandScreenLayout.floatingSideInset) #expect( trailingFrame.maxX == display.visibleFrame.maxX - AgentIslandScreenLayout.floatingSideInset) }
@Test func floatingPositionsAreIndependentAndCenteredByDefault() { var positions = AgentIslandFloatingPositions()
#expect(positions.normalizedPosition(for: "first") == 0.5) positions.setNormalizedPosition(0.25, for: "first") positions.setNormalizedPosition(0.75, for: "second")
#expect(positions.normalizedPosition(for: "first") == 0.25) #expect(positions.normalizedPosition(for: "second") == 0.75) #expect(positions.normalizedPosition(for: "unknown") == 0.5) }
@Test func centeredFloatingPositionDoesNotLeaveRedundantState() { var positions = AgentIslandFloatingPositions() positions.setNormalizedPosition(0.25, for: "external") #expect(!positions.isEmpty)
positions.setNormalizedPosition(0.5, for: "external")
#expect(positions.isEmpty) }
@Test func floatingSilentOpacityIsClampedToTheUsefulRange() { #expect(AgentIslandOpacityPolicy.normalizedSilentOpacity(0.05) == 0.2) #expect(AgentIslandOpacityPolicy.normalizedSilentOpacity(0.6) == 0.6) #expect(AgentIslandOpacityPolicy.normalizedSilentOpacity(2) == 1) #expect( AgentIslandOpacityPolicy.normalizedSilentOpacity(.nan) == AgentIslandOpacityPolicy.defaultSilentOpacity ) }
@Test func onlyAFloatingSilentIslandWithoutAttentionUsesTheConfiguredOpacity() { #expect( AgentIslandOpacityPolicy.opacity( isFloating: true, isSilent: true, isRosterExpanded: false, hasAttentionEntries: false, silentOpacity: 0.4 ) == 0.4 ) #expect( AgentIslandOpacityPolicy.opacity( isFloating: true, isSilent: false, isRosterExpanded: false, hasAttentionEntries: false, silentOpacity: 0.4 ) == 1 ) #expect( AgentIslandOpacityPolicy.opacity( isFloating: false, isSilent: true, isRosterExpanded: false, hasAttentionEntries: false, silentOpacity: 0.4 ) == 1 ) #expect( AgentIslandOpacityPolicy.opacity( isFloating: true, isSilent: true, isRosterExpanded: false, hasAttentionEntries: true, silentOpacity: 0.4 ) == 1 ) #expect( AgentIslandOpacityPolicy.opacity( isFloating: true, isSilent: true, isRosterExpanded: true, hasAttentionEntries: false, silentOpacity: 0.4 ) == 1 ) }
@Test func silentEligibilityRequiresACollapsedInactiveRoster() { #expect( AgentIslandOpacityPolicy.shouldEnterSilentState( isFloating: true, isRosterExpanded: false, hasAttentionEntries: false, isHovering: false, isControlPresented: false )) #expect( !AgentIslandOpacityPolicy.shouldEnterSilentState( isFloating: true, isRosterExpanded: true, hasAttentionEntries: false, isHovering: false, isControlPresented: false )) #expect( !AgentIslandOpacityPolicy.shouldEnterSilentState( isFloating: true, isRosterExpanded: false, hasAttentionEntries: true, isHovering: false, isControlPresented: false )) #expect( !AgentIslandOpacityPolicy.shouldEnterSilentState( isFloating: true, isRosterExpanded: false, hasAttentionEntries: false, isHovering: true, isControlPresented: false )) }
// MARK: Settings picker selection
@Test func displaySelectionMatchesStoredDisplayByIDOnly() { // `localizedName` changes with the system language; the picker must still find the tag. let stored = AgentIslandDisplayPreference.display(id: "uuid-1", name: "Built-in Display") let renamed = AgentIslandDisplayPreference.display(id: "uuid-1", name: "内建显示器")
#expect(AgentIslandDisplaySelection(stored) == .display(id: "uuid-1")) #expect(AgentIslandDisplaySelection(stored) == AgentIslandDisplaySelection(renamed)) #expect(AgentIslandDisplaySelection(.automatic) == .automatic) }
@Test func displaySelectionTakesTheConnectedDisplayNameFromTheCatalog() { let connected = screen(id: "uuid-1", name: "内建显示器") let stored = AgentIslandDisplayPreference.display(id: "uuid-1", name: "Built-in Display")
let resolved = AgentIslandDisplaySelection.display(id: "uuid-1") .preference(screens: [connected], current: stored)
#expect(resolved == .display(id: "uuid-1", name: "内建显示器")) }
@Test func displaySelectionKeepsTheStoredNameOfADisconnectedDisplay() { let stored = AgentIslandDisplayPreference.display(id: "uuid-2", name: "Studio Display")
let resolved = AgentIslandDisplaySelection.display(id: "uuid-2") .preference(screens: [screen(id: "uuid-1")], current: stored)
#expect(resolved == stored) }
@Test func displaySelectionFallsBackToTheIDWhenNoNameIsKnown() { let resolved = AgentIslandDisplaySelection.display(id: "uuid-3") .preference(screens: [], current: .automatic)
#expect(resolved == .display(id: "uuid-3", name: "uuid-3")) }
@Test func automaticSelectionClearsThePinnedDisplay() { let stored = AgentIslandDisplayPreference.display(id: "uuid-1", name: "Studio Display")
let resolved = AgentIslandDisplaySelection.automatic .preference(screens: [screen(id: "uuid-1")], current: stored)
#expect(resolved == .automatic) }
private func screen( id: String, name: String? = nil, origin: CGPoint = .zero, visibleTopInset: CGFloat = 24, isBuiltIn: Bool = false, hasNotch: Bool = false ) -> AgentIslandScreenDescriptor { let frame = CGRect(origin: origin, size: CGSize(width: 1_920, height: 1_080)) return AgentIslandScreenDescriptor( id: id, name: name ?? id, frame: frame, visibleFrame: CGRect( x: frame.minX, y: frame.minY, width: frame.width, height: frame.height - visibleTopInset ), isBuiltIn: isBuiltIn, notchFrame: hasNotch ? CGRect(x: frame.midX - 92.5, y: frame.maxY - 32, width: 185, height: 32) : nil ) }}