Skip to content

Commit 6e66ab7

Browse files
committed
Add Tests
1 parent 858068b commit 6e66ab7

File tree

11 files changed

+209
-52
lines changed

11 files changed

+209
-52
lines changed

CodeEdit.xcodeproj/project.pbxproj

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@
402402
6C48D8F72972E5F300D6D205 /* WindowObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C48D8F62972E5F300D6D205 /* WindowObserver.swift */; };
403403
6C4E37F62C73DA5200AEE7B5 /* UtilityAreaTerminalSidebar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C4E37F52C73DA5200AEE7B5 /* UtilityAreaTerminalSidebar.swift */; };
404404
6C4E37FC2C73E00700AEE7B5 /* SwiftTerm in Frameworks */ = {isa = PBXBuildFile; productRef = 6C4E37FB2C73E00700AEE7B5 /* SwiftTerm */; };
405+
6C510CB02D2E3547006EBE85 /* UtilityAreaViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C510CAF2D2E3547006EBE85 /* UtilityAreaViewModelTests.swift */; };
405406
6C5228B529A868BD00AC48F6 /* Environment+ContentInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C5228B429A868BD00AC48F6 /* Environment+ContentInsets.swift */; };
406407
6C53AAD829A6C4FD00EE9ED6 /* SplitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C53AAD729A6C4FD00EE9ED6 /* SplitView.swift */; };
407408
6C578D8129CD294800DC73B2 /* ExtensionActivatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C578D8029CD294800DC73B2 /* ExtensionActivatorView.swift */; };
@@ -1094,6 +1095,7 @@
10941095
6C48D8F32972DB1A00D6D205 /* Env+Window.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Env+Window.swift"; sourceTree = "<group>"; };
10951096
6C48D8F62972E5F300D6D205 /* WindowObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowObserver.swift; sourceTree = "<group>"; };
10961097
6C4E37F52C73DA5200AEE7B5 /* UtilityAreaTerminalSidebar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UtilityAreaTerminalSidebar.swift; sourceTree = "<group>"; };
1098+
6C510CAF2D2E3547006EBE85 /* UtilityAreaViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UtilityAreaViewModelTests.swift; sourceTree = "<group>"; };
10971099
6C5228B429A868BD00AC48F6 /* Environment+ContentInsets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Environment+ContentInsets.swift"; sourceTree = "<group>"; };
10981100
6C53AAD729A6C4FD00EE9ED6 /* SplitView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitView.swift; sourceTree = "<group>"; };
10991101
6C578D8029CD294800DC73B2 /* ExtensionActivatorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExtensionActivatorView.swift; sourceTree = "<group>"; };
@@ -2066,6 +2068,7 @@
20662068
613899BD2B6E70E200A5CAF6 /* Search */,
20672069
61FB03A92C3C1FC4001B3671 /* Tasks */,
20682070
6141CF392C3DA4180073BC9F /* TerminalEmulator */,
2071+
6C510CAE2D2E351E006EBE85 /* UtilityArea */,
20692072
);
20702073
path = Features;
20712074
sourceTree = "<group>";
@@ -2673,8 +2676,7 @@
26732676
6C1F3DA12C18C55800F6DEF6 /* ShellIntegrationTests.swift */,
26742677
61FB03AA2C3C1FD5001B3671 /* Shell */,
26752678
);
2676-
name = TerminalEmulator;
2677-
path = ActivityViewer/TerminalEmulator;
2679+
path = TerminalEmulator;
26782680
sourceTree = "<group>";
26792681
};
26802682
617DB3CE2C25AF5B00B58BFE /* ActivityViewer */ = {
@@ -2950,6 +2952,14 @@
29502952
path = Environment;
29512953
sourceTree = "<group>";
29522954
};
2955+
6C510CAE2D2E351E006EBE85 /* UtilityArea */ = {
2956+
isa = PBXGroup;
2957+
children = (
2958+
6C510CAF2D2E3547006EBE85 /* UtilityAreaViewModelTests.swift */,
2959+
);
2960+
path = UtilityArea;
2961+
sourceTree = "<group>";
2962+
};
29532963
6C6BD6ED29CD123000235D17 /* Extensions */ = {
29542964
isa = PBXGroup;
29552965
children = (
@@ -3442,10 +3452,10 @@
34423452
B676606A2AA973A500CD56B0 /* TerminalUtility */ = {
34433453
isa = PBXGroup;
34443454
children = (
3445-
B62AEDB22A1FD95B009A9F52 /* UtilityAreaTerminalView.swift */,
34463455
6CCEE7F42D2C91F700B2B854 /* UtilityAreaTerminalPicker.swift */,
3447-
B62AEDBB2A210DBB009A9F52 /* UtilityAreaTerminalTab.swift */,
34483456
6C4E37F52C73DA5200AEE7B5 /* UtilityAreaTerminalSidebar.swift */,
3457+
B62AEDBB2A210DBB009A9F52 /* UtilityAreaTerminalTab.swift */,
3458+
B62AEDB22A1FD95B009A9F52 /* UtilityAreaTerminalView.swift */,
34493459
);
34503460
path = TerminalUtility;
34513461
sourceTree = "<group>";
@@ -4555,6 +4565,7 @@
45554565
583E528C29361B39001AB554 /* CodeEditUITests.swift in Sources */,
45564566
6C7D6D462C9092EC00B69EE0 /* BufferingServerConnection.swift in Sources */,
45574567
613053652B23A49300D767E3 /* TemporaryFile.swift in Sources */,
4568+
6C510CB02D2E3547006EBE85 /* UtilityAreaViewModelTests.swift in Sources */,
45584569
617DB3DF2C25E13800B58BFE /* TaskNotificationHandlerTests.swift in Sources */,
45594570
775566502C27FD1B001E7A4D /* CodeFileDocument+UTTypeTests.swift in Sources */,
45604571
587B60F82934124200D5CD8F /* CEWorkspaceFileManagerTests.swift in Sources */,

CodeEdit/Features/SplitView/Views/SplitView.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,6 @@ struct SplitView<Content: View>: View {
2525
}
2626
}
2727
._trait(SplitViewControllerLayoutValueKey.self, viewController)
28+
.accessibilityElement(children: .contain)
2829
}
2930
}

CodeEdit/Features/UtilityArea/TerminalUtility/UtilityAreaTerminalSidebar.swift

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,37 +26,37 @@ struct UtilityAreaTerminalSidebar: View {
2626
.listRowSeparator(.hidden)
2727
}
2828
.onMove { [weak utilityAreaViewModel] (source, destination) in
29-
utilityAreaViewModel?.moveItems(from: source, to: destination)
29+
utilityAreaViewModel?.reorderTerminals(from: source, to: destination)
3030
}
3131
}
3232
.focusedObject(utilityAreaViewModel)
3333
.listStyle(.automatic)
3434
.accentColor(.secondary)
3535
.contextMenu {
3636
Button("New Terminal") {
37-
utilityAreaViewModel.addTerminal(workspace: workspace)
37+
utilityAreaViewModel.addTerminal(rootURL: workspace.fileURL)
3838
}
3939
Menu("New Terminal With Profile") {
4040
Button("Default") {
41-
utilityAreaViewModel.addTerminal(workspace: workspace)
41+
utilityAreaViewModel.addTerminal(rootURL: workspace.fileURL)
4242
}
4343
Divider()
4444
ForEach(Shell.allCases, id: \.self) { shell in
4545
Button(shell.rawValue) {
46-
utilityAreaViewModel.addTerminal(shell: shell, workspace: workspace)
46+
utilityAreaViewModel.addTerminal(shell: shell, rootURL: workspace.fileURL)
4747
}
4848
}
4949
}
5050
}
5151
.onChange(of: utilityAreaViewModel.terminals) { newValue in
5252
if newValue.isEmpty {
53-
utilityAreaViewModel.addTerminal(workspace: workspace)
53+
utilityAreaViewModel.addTerminal(rootURL: workspace.fileURL)
5454
}
5555
}
5656
.paneToolbar {
5757
PaneToolbarSection {
5858
Button {
59-
utilityAreaViewModel.addTerminal(workspace: workspace)
59+
utilityAreaViewModel.addTerminal(rootURL: workspace.fileURL)
6060
} label: {
6161
Image(systemName: "plus")
6262
}
@@ -70,6 +70,8 @@ struct UtilityAreaTerminalSidebar: View {
7070
}
7171
Spacer()
7272
}
73+
.accessibilityElement(children: .contain)
74+
.accessibilityLabel("Terminals")
7375
}
7476
}
7577

CodeEdit/Features/UtilityArea/TerminalUtility/UtilityAreaTerminalTab.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ struct UtilityAreaTerminalTab: View {
4646
}
4747
} icon: {
4848
Image(systemName: "terminal")
49+
.accessibilityHidden(true)
4950
}
5051
.contextMenu {
5152
Button("Rename...") {

CodeEdit/Features/UtilityArea/TerminalUtility/UtilityAreaTerminalView.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ struct UtilityAreaTerminalView: View {
138138
guard let terminal = getSelectedTerminal() else {
139139
return
140140
}
141-
utilityAreaViewModel.addTerminal(shell: nil, workspace: workspace, replacing: terminal.id)
141+
utilityAreaViewModel.replaceTerminal(terminal.id)
142142
} label: {
143143
Image(systemName: "trash")
144144
}
@@ -161,7 +161,11 @@ struct UtilityAreaTerminalView: View {
161161
UtilityAreaTerminalSidebar()
162162
}
163163
.onAppear {
164-
utilityAreaViewModel.initializeTerminals(workspace)
164+
guard let workspaceURL = workspace.fileURL else {
165+
assertionFailure("Workspace does not have a file URL.")
166+
return
167+
}
168+
utilityAreaViewModel.initializeTerminals(workspaceURL: workspaceURL)
165169
}
166170
}
167171

CodeEdit/Features/UtilityArea/ViewModels/UtilityAreaViewModel.swift

Lines changed: 60 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,7 @@ class UtilityAreaViewModel: ObservableObject {
3333
/// The tab bar view model for UtilityAreaTabView
3434
@Published var tabViewModel = UtilityAreaTabViewModel()
3535

36-
func removeTerminals(_ ids: Set<UUID>) {
37-
for (idx, terminal) in terminals.enumerated().reversed()
38-
where ids.contains(terminal.id) {
39-
TerminalCache.shared.removeCachedView(terminal.id)
40-
terminals.remove(at: idx)
41-
}
42-
43-
selectedTerminals = [terminals.last?.id ?? UUID()]
44-
}
36+
// MARK: - State Restoration
4537

4638
func restoreFromState(_ workspace: WorkspaceDocument) {
4739
isCollapsed = workspace.getFromWorkspaceState(.utilityAreaCollapsed) as? Bool ?? false
@@ -62,6 +54,25 @@ class UtilityAreaViewModel: ObservableObject {
6254

6355
// MARK: - Terminal Management
6456

57+
/// Removes all terminals included in the given set and selects a new terminal if the selection was modified.
58+
/// The new selection is either the same selection minus the ids removed, or if that's empty the last terminal.
59+
/// - Parameter ids: A set of all terminal ids to remove.
60+
func removeTerminals(_ ids: Set<UUID>) {
61+
for (idx, terminal) in terminals.enumerated().reversed()
62+
where ids.contains(terminal.id) {
63+
TerminalCache.shared.removeCachedView(terminal.id)
64+
terminals.remove(at: idx)
65+
}
66+
67+
var newSelection = selectedTerminals.subtracting(ids)
68+
69+
if newSelection.isEmpty, let terminal = terminals.last {
70+
newSelection = [terminal.id]
71+
}
72+
73+
selectedTerminals = newSelection
74+
}
75+
6576
/// Update a terminal's title.
6677
/// - Parameters:
6778
/// - id: The id of the terminal to update.
@@ -81,56 +92,65 @@ class UtilityAreaViewModel: ObservableObject {
8192

8293
/// Create a new terminal if there are no existing terminals.
8394
/// Will not perform any action if terminals exist in the ``terminals`` array.
84-
/// - Parameter workspace: The workspace to use to find the default path.
85-
func initializeTerminals(_ workspace: WorkspaceDocument) {
95+
/// - Parameter workspaceURL: The base url of the workspace, to initialize terminals.l
96+
func initializeTerminals(workspaceURL: URL) {
8697
guard terminals.isEmpty else { return }
87-
addTerminal(shell: nil, workspace: workspace)
98+
addTerminal(rootURL: workspaceURL)
8899
}
89100

90-
/// Add a new terminal to the workspace and selects it. Optionally replaces an existing terminal
91-
///
92-
/// Terminals being replaced will have the `SIGKILL` signal sent to the running shell. The new terminal will
93-
/// inherit the same `url` and `shell` parameters from the old one, in case they were specified.
94-
///
101+
/// Add a new terminal to the workspace and selects it.
95102
/// - Parameters:
96103
/// - shell: The shell to use, `nil` if auto-detect the default shell.
97-
/// - workspace: The workspace to use to find the default path.
98-
/// - replacing: The ID of a terminal to replace with a new terminal. If left `nil`, will ignore.
99-
func addTerminal(shell: Shell? = nil, workspace: WorkspaceDocument, replacing: UUID? = nil) {
104+
/// - rootURL: The url to start the new terminal at. If left `nil` defaults to the user's home directory.
105+
func addTerminal(shell: Shell? = nil, rootURL: URL?) {
100106
let id = UUID()
101107

102-
if let replacing, let index = terminals.firstIndex(where: { $0.id == replacing }) {
103-
let url = terminals[index].url
104-
let shell = terminals[index].shell
105-
if let shellPid = TerminalCache.shared.getTerminalView(replacing)?.process.shellPid {
106-
kill(shellPid, SIGKILL)
107-
}
108-
terminals[index] = UtilityAreaTerminal(
108+
terminals.append(
109+
UtilityAreaTerminal(
109110
id: id,
110-
url: url,
111-
title: "terminal",
111+
url: rootURL ?? URL(filePath: "~/"),
112+
title: shell?.rawValue ?? "terminal",
112113
shell: shell
113114
)
114-
TerminalCache.shared.removeCachedView(replacing)
115-
} else {
116-
terminals.append(
117-
UtilityAreaTerminal(
118-
id: id,
119-
url: workspace.workspaceFileManager?.folderUrl ?? URL(filePath: "/"),
120-
title: "terminal",
121-
shell: shell
122-
)
123-
)
115+
)
116+
117+
selectedTerminals = [id]
118+
}
119+
120+
/// Replaces the terminal with a given ID, killing the shell and restarting it at the same directory.
121+
///
122+
/// Terminals being replaced will have the `SIGKILL` signal sent to the running shell. The new terminal will
123+
/// inherit the same `url` and `shell` parameters from the old one.
124+
/// - Parameter replacing: The ID of a terminal to replace with a new terminal.
125+
func replaceTerminal(_ replacing: UUID) {
126+
guard let index = terminals.firstIndex(where: { $0.id == replacing }) else {
127+
return
124128
}
125129

130+
let id = UUID()
131+
let url = terminals[index].url
132+
let shell = terminals[index].shell
133+
if let shellPid = TerminalCache.shared.getTerminalView(replacing)?.process.shellPid {
134+
kill(shellPid, SIGKILL)
135+
}
136+
137+
terminals[index] = UtilityAreaTerminal(
138+
id: id,
139+
url: url,
140+
title: shell?.rawValue ?? "terminal",
141+
shell: shell
142+
)
143+
TerminalCache.shared.removeCachedView(replacing)
144+
126145
selectedTerminals = [id]
146+
return
127147
}
128148

129149
/// Reorders terminals in the ``utilityAreaViewModel``.
130150
/// - Parameters:
131151
/// - source: The source indices.
132152
/// - destination: The destination indices.
133-
func moveItems(from source: IndexSet, to destination: Int) {
153+
func reorderTerminals(from source: IndexSet, to destination: Int) {
134154
terminals.move(fromOffsets: source, toOffset: destination)
135155
}
136156
}

CodeEdit/Features/UtilityArea/Views/UtilityAreaView.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,7 @@ struct UtilityAreaView: View {
4141
.overlay(Color(nsColor: colorScheme == .dark ? .black : .clear))
4242
}
4343
}
44+
.accessibilityElement(children: .contain)
45+
.accessibilityLabel("Utility Area")
4446
}
4547
}

CodeEdit/WorkspaceView.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ struct WorkspaceView: View {
8282
}
8383
}
8484
}
85+
.accessibilityHidden(true)
8586
}
8687
.edgesIgnoringSafeArea(.top)
8788
.frame(maxWidth: .infinity, maxHeight: .infinity)
@@ -100,6 +101,7 @@ struct WorkspaceView: View {
100101
}
101102
.offset(y: utilityAreaViewModel.isMaximized ? 0 : editorsHeight - statusbarHeight)
102103
}
104+
.accessibilityElement(children: .contain)
103105
}
104106
.onChange(of: focusedEditor) { newValue in
105107
/// update active tab group only if the new one is not the same with it.

CodeEditTests/Features/ActivityViewer/TerminalEmulator/Shell/ShellTests.swift renamed to CodeEditTests/Features/TerminalEmulator/Shell/ShellTests.swift

File renamed without changes.

CodeEditTests/Features/ActivityViewer/TerminalEmulator/ShellIntegrationTests.swift renamed to CodeEditTests/Features/TerminalEmulator/ShellIntegrationTests.swift

File renamed without changes.

0 commit comments

Comments
 (0)