aerospace fork
Something went wrong. Try again.
17 kB · 388 lines
Swift
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389@testable import AppBundleimport Commonimport XCTest
@MainActorfinal class LayoutCommandTest: XCTestCase { override func setUp() async throws { setUpWorkspacesForTests() }
func testParse() { assertNil(parseCommand("layout v_tiles h_tiles").errorOrNil) assertNil(parseCommand("layout tiling").errorOrNil) assertNil(parseCommand("layout floating tiling").errorOrNil) assertNil(parseCommand("layout --window-id 1 horizontal vertical").errorOrNil)
testParseCommandFail( "layout --root accordion tiling", msg: "layout command: --root and tiling|floating are incompatible", exitCode: 2, ) testParseSingleCommandSucc( "layout --root accordion tiles", LayoutCmdArgs(rawArgs: [], toggleBetween: [.accordion, .tiles]).copy(\.root, true), ) testParseCommandFail( "layout --workspace 2 tiles", msg: "--workspace flag requires using an explicit --root flag", exitCode: 2, ) testParseCommandFail( "layout --workspace 2 --window-id 2 tiles", msg: "ERROR: Conflicting options: --window-id, --workspace", exitCode: 2, ) testParseCommandFail( "layout --fail-if-noop accordion tiling", msg: "--fail-if-noop allows only one <target-layout> argument", exitCode: 2, ) }
func testChangeOrientation() async { let root = Workspace.get(byName: name).rootTilingContainer.apply { assertEquals(TestWindow.new(id: 1, parent: $0).focusWindow(), true) TestWindow.new(id: 2, parent: $0) } assertEquals(root.orientation, .h)
await parseCommand("layout vertical").cmdOrDie.run(.defaultEnv, .emptyStdin) assertEquals(root.orientation, .v) assertEquals(root.layoutDescription, .v_tiles([.window(1), .window(2)])) }
func testChangeLayoutToAccordion() async { let root = Workspace.get(byName: name).rootTilingContainer.apply { assertEquals(TestWindow.new(id: 1, parent: $0).focusWindow(), true) TestWindow.new(id: 2, parent: $0) } assertEquals(root.layout, .tiles)
await parseCommand("layout accordion").cmdOrDie.run(.defaultEnv, .emptyStdin) assertEquals(root.layout, .accordion) assertEquals(root.layoutDescription, .h_accordion([.window(1), .window(2)])) }
func testChangeLayoutToMasterStack() async { let root = Workspace.get(byName: name).rootTilingContainer.apply { assertEquals(TestWindow.new(id: 1, parent: $0).focusWindow(), true) TestWindow.new(id: 2, parent: $0) } assertEquals(root.layout, .tiles)
await parseCommand("layout master-stack").cmdOrDie.run(.defaultEnv, .emptyStdin) assertEquals(root.layout, .masterStack) assertEquals(root.layoutDescription, .h_master_stack([.window(1), .window(2)])) }
func testChangeLayoutToMasterStackWithOrientation() async { let root = Workspace.get(byName: name).rootTilingContainer.apply { assertEquals(TestWindow.new(id: 1, parent: $0).focusWindow(), true) TestWindow.new(id: 2, parent: $0) }
await parseCommand("layout v_master-stack").cmdOrDie.run(.defaultEnv, .emptyStdin) assertEquals(root.layout, .masterStack) assertEquals(root.orientation, .v) assertEquals(root.layoutDescription, .v_master_stack([.window(1), .window(2)])) }
func testToggleBetweenTilesAndMasterStack() async { let root = Workspace.get(byName: name).rootTilingContainer.apply { assertEquals(TestWindow.new(id: 1, parent: $0).focusWindow(), true) TestWindow.new(id: 2, parent: $0) } assertEquals(root.layout, .tiles)
await parseCommand("layout h_tiles h_master-stack").cmdOrDie.run(.defaultEnv, .emptyStdin) assertEquals(root.layout, .masterStack)
await parseCommand("layout h_tiles h_master-stack").cmdOrDie.run(.defaultEnv, .emptyStdin) assertEquals(root.layout, .tiles) }
func testChangeBothLayoutAndOrientation() async { let root = Workspace.get(byName: name).rootTilingContainer.apply { assertEquals(TestWindow.new(id: 1, parent: $0).focusWindow(), true) TestWindow.new(id: 2, parent: $0) }
await parseCommand("layout v_accordion").cmdOrDie.run(.defaultEnv, .emptyStdin) assertEquals(root.layout, .accordion) assertEquals(root.orientation, .v) assertEquals(root.layoutDescription, .v_accordion([.window(1), .window(2)])) }
func testToggleBetween_skipsMatching() async { let root = Workspace.get(byName: name).rootTilingContainer.apply { assertEquals(TestWindow.new(id: 1, parent: $0).focusWindow(), true) TestWindow.new(id: 2, parent: $0) }
await parseCommand("layout h_tiles h_accordion").cmdOrDie.run(.defaultEnv, .emptyStdin) assertEquals(root.layout, .accordion) assertEquals(root.orientation, .h) }
func testToggleBetween_allMatch_fails() async { let root = Workspace.get(byName: name).rootTilingContainer.apply { assertEquals(TestWindow.new(id: 1, parent: $0).focusWindow(), true) TestWindow.new(id: 2, parent: $0) }
let result = await parseCommand("layout h_tiles").cmdOrDie.run(.defaultEnv, .emptyStdin) assertEquals(result.exitCode.rawValue, 0) assertEquals(root.layoutDescription, .h_tiles([.window(1), .window(2)])) }
func testEmptyWorkspace_changeOrientation() async { let workspace = Workspace.get(byName: name) assertTrue(workspace.isEffectivelyEmpty)
let result = await parseCommand("layout v_tiles").cmdOrDie .run(.defaultEnv.withWorkspaceName(name), .emptyStdin) assertEquals(result.exitCode.rawValue, 0) assertEquals(workspace.rootTilingContainer.orientation, .v) assertEquals(workspace.rootTilingContainer.layout, .tiles) }
func testEmptyWorkspace_changeLayout() async { let workspace = Workspace.get(byName: name) assertTrue(workspace.isEffectivelyEmpty)
let result = await parseCommand("layout accordion").cmdOrDie .run(.defaultEnv.withWorkspaceName(name), .emptyStdin) assertEquals(result.exitCode.rawValue, 0) assertEquals(workspace.rootTilingContainer.layout, .accordion) assertEquals(workspace.rootTilingContainer.orientation, .h) }
func testEmptyWorkspace_alreadyMatches_fails() async { let workspace = Workspace.get(byName: name) assertTrue(workspace.isEffectivelyEmpty)
let result = await parseCommand("layout h_tiles").cmdOrDie .run(.defaultEnv.withWorkspaceName(name), .emptyStdin) assertEquals(result.exitCode.rawValue, 0) assertEquals(workspace.rootTilingContainer.layout, .tiles) assertEquals(workspace.rootTilingContainer.orientation, .h) }
func testEmptyWorkspace_floating_fails() async { let workspace = Workspace.get(byName: name) let result = await parseCommand("layout floating").cmdOrDie .run(.defaultEnv.withWorkspaceName(name), .emptyStdin) assertEquals(result.exitCode.rawValue, 2) assertEquals(result.stderr, [noWindowIsFocused]) assertTrue(workspace.isEffectivelyEmpty) }
func testEmptyWorkspace_tiling_fails() async { let workspace = Workspace.get(byName: name) let result = await parseCommand("layout tiling").cmdOrDie .run(.defaultEnv.withWorkspaceName(name), .emptyStdin) assertEquals(result.exitCode.rawValue, 0) assertEquals(result.stderr, ["Already in the requested tiling mode. Tip: use --fail-if-noop to exit with non-zero exit code"]) assertTrue(workspace.isEffectivelyEmpty) }
func testEmptyWorkspace_tiling_failIfNoop() async { let workspace = Workspace.get(byName: name) let result = await parseCommand("layout tiling --fail-if-noop").cmdOrDie .run(.defaultEnv.withWorkspaceName(name), .emptyStdin) assertEquals(result.exitCode.rawValue, 2) assertEquals(result.stderr, []) assertTrue(workspace.isEffectivelyEmpty) }
func testTilingToFloating() async { let workspace = Workspace.get(byName: name) let root = workspace.rootTilingContainer.apply { assertEquals(TestWindow.new(id: 1, parent: $0).focusWindow(), true) TestWindow.new(id: 2, parent: $0) }
await parseCommand("layout floating").cmdOrDie.run(.defaultEnv, .emptyStdin) assertEquals(root.layoutDescription, .h_tiles([.window(2)])) assertEquals(workspace.floatingWindows.map(\.windowId), [1]) assertEquals(focus.windowOrNil?.windowId, 1) }
func testFloatingToTiling() async { let workspace = Workspace.get(byName: name) workspace.floatingWindowsContainer.apply { assertEquals(TestWindow.new(id: 1, parent: $0).focusWindow(), true) } assertEquals(workspace.floatingWindows.map(\.windowId), [1])
await parseCommand("layout tiling").cmdOrDie.run(.defaultEnv, .emptyStdin) assertEquals(workspace.floatingWindows, []) assertEquals(workspace.rootTilingContainer.layoutDescription, .h_tiles([.window(1)])) }
func testLayoutTilingOnTiledWindow_isNoop() async { let workspace = Workspace.get(byName: name) let root = workspace.rootTilingContainer.apply { assertEquals(TestWindow.new(id: 1, parent: $0).focusWindow(), true) TestWindow.new(id: 2, parent: $0) }
let result = await parseCommand("layout tiling").cmdOrDie.run(.defaultEnv, .emptyStdin) assertEquals(result.exitCode.rawValue, 0) assertEquals(root.layoutDescription, .h_tiles([.window(1), .window(2)])) }
func testLayoutFloatingOnFloatingWindow_isNoop() async { let workspace = Workspace.get(byName: name) workspace.floatingWindowsContainer.apply { assertEquals(TestWindow.new(id: 1, parent: $0).focusWindow(), true) }
let result = await parseCommand("layout floating").cmdOrDie.run(.defaultEnv, .emptyStdin) assertEquals(result.exitCode.rawValue, 0) assertEquals(workspace.floatingWindows.map(\.windowId), [1]) }
func testChangeTilingLayoutOnFloatingWindow_fails() async { let workspace = Workspace.get(byName: name) workspace.floatingWindowsContainer.apply { assertEquals(TestWindow.new(id: 1, parent: $0).focusWindow(), true) }
let result = await parseCommand("layout v_tiles").cmdOrDie.run(.defaultEnv, .emptyStdin) assertEquals(result.exitCode.rawValue, 2) assertEquals(result.stderr, ["The window is non-tiling"]) assertEquals(workspace.floatingWindows.map(\.windowId), [1]) }
func testTogglesAcrossFloatingAndTiling() async { let workspace = Workspace.get(byName: name) workspace.floatingWindowsContainer.apply { assertEquals(TestWindow.new(id: 1, parent: $0).focusWindow(), true) }
// The window is floating, so [.floating, .tiling] picks .tiling await parseCommand("layout floating tiling").cmdOrDie.run(.defaultEnv, .emptyStdin) assertEquals(workspace.rootTilingContainer.layoutDescription, .h_tiles([.window(1)]))
// Now it's tiled, so the same toggle picks .floating await parseCommand("layout floating tiling").cmdOrDie.run(.defaultEnv, .emptyStdin) assertEquals(workspace.floatingWindows.map(\.windowId), [1]) }
func testRoot_changesRootInsteadOfNestedParent() async { let root = Workspace.get(byName: name).rootTilingContainer.apply { TilingContainer.newVTiles(parent: $0, adaptiveWeight: 1).apply { assertEquals(TestWindow.new(id: 1, parent: $0).focusWindow(), true) } TestWindow.new(id: 2, parent: $0) } assertEquals(root.orientation, .h) assertEquals(root.layout, .tiles)
await parseCommand("layout --root v_accordion").cmdOrDie.run(.defaultEnv, .emptyStdin) assertEquals(root.layout, .accordion) assertEquals(root.orientation, .v) assertEquals(root.layoutDescription, .v_accordion([ .v_tiles([.window(1)]), .window(2), ])) }
func testRoot_emptyWorkspace_changeLayout() async { let workspace = Workspace.get(byName: name) assertTrue(workspace.isEffectivelyEmpty)
let result = await parseCommand("layout --root accordion").cmdOrDie .run(.defaultEnv.withWorkspaceName(name), .emptyStdin) assertEquals(result.exitCode.rawValue, 0) assertEquals(workspace.rootTilingContainer.layout, .accordion) assertEquals(workspace.rootTilingContainer.orientation, .h) }
func testRoot_floatingFocusedWindow_changesRootTilingContainer() async { let workspace = Workspace.get(byName: name) workspace.floatingWindowsContainer.apply { assertEquals(TestWindow.new(id: 1, parent: $0).focusWindow(), true) }
await parseCommand("layout --root v_accordion").cmdOrDie.run(.defaultEnv, .emptyStdin) assertEquals(workspace.rootTilingContainer.layout, .accordion) assertEquals(workspace.rootTilingContainer.orientation, .v) assertEquals(workspace.floatingWindows.map(\.windowId), [1]) }
func testRoot_macosFullscreenFocusedWindow_changesRootTilingContainer() async { let workspace = Workspace.get(byName: name) assertEquals(TestWindow.new(id: 1, parent: workspace.macOsNativeFullscreenWindowsContainer).focusWindow(), true)
// Without --root this would fail with "Can't change layout for macOS minimized, fullscreen…". await parseCommand("layout --root v_accordion").cmdOrDie.run(.defaultEnv, .emptyStdin) assertEquals(workspace.rootTilingContainer.layout, .accordion) assertEquals(workspace.rootTilingContainer.orientation, .v) }
func testRoot_withWindowIdFlag_targetsThatWindowsWorkspaceRoot() async { let focusedRoot = Workspace.get(byName: "a").rootTilingContainer.apply { assertEquals(TestWindow.new(id: 1, parent: $0).focusWindow(), true) } let otherRoot = Workspace.get(byName: "b").rootTilingContainer.apply { TestWindow.new(id: 2, parent: $0) } assertEquals(focusedRoot.layout, .tiles) assertEquals(otherRoot.layout, .tiles)
await parseCommand("layout --root --window-id 2 v_accordion").cmdOrDie.run(.defaultEnv, .emptyStdin) assertEquals(otherRoot.layout, .accordion) assertEquals(otherRoot.orientation, .v) assertEquals(focusedRoot.layout, .tiles) // Focused workspace must be untouched }
func testRoot_withWorkspaceFlag_targetsThatWorkspace() async { let focusedRoot = Workspace.get(byName: "a").rootTilingContainer.apply { assertEquals(TestWindow.new(id: 1, parent: $0).focusWindow(), true) } let otherRoot = Workspace.get(byName: "b").rootTilingContainer.apply { TestWindow.new(id: 2, parent: $0) } assertEquals(focusedRoot.layout, .tiles) assertEquals(otherRoot.layout, .tiles)
await parseCommand("layout --root --workspace b v_accordion").cmdOrDie.run(.defaultEnv, .emptyStdin) assertEquals(otherRoot.layout, .accordion) assertEquals(otherRoot.orientation, .v) assertEquals(focusedRoot.layout, .tiles) // Focused workspace must be untouched }
func testRoot_toggleBetween_skipsMatching() async { let root = Workspace.get(byName: name).rootTilingContainer.apply { TilingContainer.newVTiles(parent: $0, adaptiveWeight: 1).apply { assertEquals(TestWindow.new(id: 1, parent: $0).focusWindow(), true) } TestWindow.new(id: 2, parent: $0) } assertEquals(root.layoutDescription, .h_tiles([ .v_tiles([.window(1)]), .window(2), ]))
await parseCommand("layout --root h_tiles h_accordion").cmdOrDie.run(.defaultEnv, .emptyStdin) assertEquals(root.layout, .accordion) assertEquals(root.orientation, .h) assertEquals(root.layoutDescription, .h_accordion([ .v_tiles([.window(1)]), .window(2), ])) }
func testRoot_alreadyMatches_fails() async { let root = Workspace.get(byName: name).rootTilingContainer.apply { assertEquals(TestWindow.new(id: 1, parent: $0).focusWindow(), true) TestWindow.new(id: 2, parent: $0) } assertEquals(root.layoutDescription, .h_tiles([.window(1), .window(2)]))
let result = await parseCommand("layout --root h_tiles").cmdOrDie.run(.defaultEnv, .emptyStdin) assertEquals(result.exitCode.rawValue, 0) assertEquals(root.layoutDescription, .h_tiles([.window(1), .window(2)])) }}