Skip to content

Commit 2eaf226

Browse files
committed
refactor(toolbar): hoist Return-to-activate and extract testable connection-switcher selection (#1350)
1 parent 45da867 commit 2eaf226

2 files changed

Lines changed: 55 additions & 5 deletions

File tree

TablePro/Views/Toolbar/ConnectionSwitcherPopover.swift

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@ enum ConnectionSwitcherFilter {
1818
}
1919
}
2020

21+
enum ConnectionSwitcherSelection {
22+
static func moved(in ids: [UUID], from current: UUID?, by offset: Int) -> UUID? {
23+
guard !ids.isEmpty else { return nil }
24+
let currentIndex = current.flatMap { ids.firstIndex(of: $0) } ?? 0
25+
let newIndex = max(0, min(ids.count - 1, currentIndex + offset))
26+
return ids[newIndex]
27+
}
28+
}
29+
2130
struct ConnectionSwitcherPopover: View {
2231
@Environment(\.dismiss) private var dismiss
2332

@@ -82,6 +91,10 @@ struct ConnectionSwitcherPopover: View {
8291
if let id = selectedConnectionId, ids.contains(id) { return }
8392
selectedConnectionId = ids.first
8493
}
94+
.onKeyPress(.return) {
95+
activateSelected()
96+
return .handled
97+
}
8598
}
8699

87100
private var searchField: some View {
@@ -281,11 +294,9 @@ struct ConnectionSwitcherPopover: View {
281294
// MARK: - Selection
282295

283296
private func moveSelection(by offset: Int) {
284-
let ids = orderedIds
285-
guard !ids.isEmpty else { return }
286-
let currentIndex = selectedConnectionId.flatMap { ids.firstIndex(of: $0) } ?? 0
287-
let newIndex = max(0, min(ids.count - 1, currentIndex + offset))
288-
selectedConnectionId = ids[newIndex]
297+
if let next = ConnectionSwitcherSelection.moved(in: orderedIds, from: selectedConnectionId, by: offset) {
298+
selectedConnectionId = next
299+
}
289300
}
290301

291302
private func activateSelected() {

TableProTests/Views/Toolbar/ConnectionSwitcherFilterTests.swift

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,48 @@ struct ConnectionSwitcherFilterTests {
3030
#expect(ConnectionSwitcherFilter.matches(connection, query: "analy"))
3131
}
3232

33+
@Test("Host is searched")
34+
func hostMatch() {
35+
let connection = TestFixtures.makeConnection(name: "Primary", database: "analytics")
36+
#expect(ConnectionSwitcherFilter.matches(connection, query: "localhost"))
37+
}
38+
3339
@Test("Non-matching query returns false")
3440
func noMatch() {
3541
let connection = TestFixtures.makeConnection(name: "Primary", database: "analytics")
3642
#expect(!ConnectionSwitcherFilter.matches(connection, query: "zzz"))
3743
}
3844
}
45+
46+
@Suite("Connection Switcher Selection")
47+
struct ConnectionSwitcherSelectionTests {
48+
@Test("Empty list yields no selection")
49+
func emptyList() {
50+
#expect(ConnectionSwitcherSelection.moved(in: [], from: nil, by: 1) == nil)
51+
}
52+
53+
@Test("Moving down advances to the next id")
54+
func movesDown() {
55+
let (a, b, c) = (UUID(), UUID(), UUID())
56+
#expect(ConnectionSwitcherSelection.moved(in: [a, b, c], from: a, by: 1) == b)
57+
#expect(ConnectionSwitcherSelection.moved(in: [a, b, c], from: b, by: 1) == c)
58+
}
59+
60+
@Test("Moving up retreats to the previous id")
61+
func movesUp() {
62+
let (a, b, c) = (UUID(), UUID(), UUID())
63+
#expect(ConnectionSwitcherSelection.moved(in: [a, b, c], from: c, by: -1) == b)
64+
}
65+
66+
@Test("Moving past the top clamps to the first id")
67+
func clampsAtTop() {
68+
let (a, b, c) = (UUID(), UUID(), UUID())
69+
#expect(ConnectionSwitcherSelection.moved(in: [a, b, c], from: a, by: -1) == a)
70+
}
71+
72+
@Test("Moving past the bottom clamps to the last id")
73+
func clampsAtBottom() {
74+
let (a, b, c) = (UUID(), UUID(), UUID())
75+
#expect(ConnectionSwitcherSelection.moved(in: [a, b, c], from: c, by: 1) == c)
76+
}
77+
}

0 commit comments

Comments
 (0)