Skip to content

Commit 025c521

Browse files
- Updated RecentProjectsTests to test out the RecentsStore
1 parent b39bb68 commit 025c521

File tree

1 file changed

+127
-55
lines changed

1 file changed

+127
-55
lines changed
Lines changed: 127 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,170 @@
11
//
2-
// RecentProjectsTests.swift
2+
// RecentsStoreTests.swift
33
// CodeEditTests
44
//
55
// Created by Khan Winter on 5/27/25.
6+
// Updated for the new RecentsStore on 6/08/25
67
//
78

89
import Testing
910
import Foundation
10-
@testable import CodeEdit
11+
@testable import WelcomeWindow // <- contains RecentsStore
12+
13+
// -----------------------------------------------------------------------------
14+
// MARK: - helpers
15+
// -----------------------------------------------------------------------------
16+
private extension URL {
17+
/// Creates an empty file (or directory) on disk, so we can successfully
18+
/// generate security-scoped bookmarks for it.
19+
///
20+
/// - parameter directory: Pass `true` to create a directory, `false`
21+
/// to create a regular file.
22+
func materialise(directory: Bool) throws {
23+
let fileManager = FileManager.default
24+
if directory {
25+
try fileManager.createDirectory(at: self, withIntermediateDirectories: true)
26+
} else {
27+
fileManager.createFile(atPath: path, contents: Data())
28+
}
29+
}
30+
31+
/// Convenience that returns a fresh URL inside the per-suite temp dir.
32+
static func temp(named name: String, directory: Bool) -> URL {
33+
TestContext.tempRoot.appendingPathComponent(
34+
name,
35+
isDirectory: directory
36+
)
37+
}
38+
}
1139

12-
// This suite needs to be serial due to the use of `UserDefaults` and sharing one testing storage location.
40+
/// A container for values that need to remain alive for the whole test-suite.
41+
private enum TestContext {
42+
/// Every run gets its own random temp folder that is cleaned up
43+
/// when the process exits.
44+
static let tempRoot: URL = {
45+
let root = FileManager.default.temporaryDirectory
46+
.appendingPathComponent("RecentsStoreTests_\(UUID())", isDirectory: true)
47+
try? FileManager.default.createDirectory(
48+
at: root,
49+
withIntermediateDirectories: true
50+
)
51+
atexit_b {
52+
try? FileManager.default.removeItem(at: root)
53+
}
54+
return root
55+
}()
56+
}
57+
58+
// -----------------------------------------------------------------------------
59+
// MARK: - Test-suite
60+
// -----------------------------------------------------------------------------
61+
62+
// Needs to be serial – everything writes to `UserDefaults.standard`.
1363
@Suite(.serialized)
14-
class RecentProjectsTests {
15-
let store: RecentProjectsStore
64+
class RecentsStoreTests {
1665

1766
init() {
18-
let defaults = UserDefaults(suiteName: #file)!
19-
defaults.removeSuite(named: #file)
20-
store = RecentProjectsStore(defaults: defaults)
67+
// Start every suite run with a clean slate.
68+
RecentsStore.clearList()
69+
UserDefaults.standard.removeObject(forKey: "recentProjectBookmarks")
2170
}
2271

2372
deinit {
24-
try? FileManager.default.removeItem(atPath: #file + ".plist")
73+
RecentsStore.clearList()
74+
UserDefaults.standard.removeObject(forKey: "recentProjectBookmarks")
2575
}
2676

77+
// -------------------------------------------------------------------------
78+
// MARK: - Tests mirroring the old suite
79+
// -------------------------------------------------------------------------
80+
2781
@Test
2882
func newStoreEmpty() {
29-
#expect(store.recentURLs().isEmpty)
83+
#expect(RecentsStore.recentProjectURLs().isEmpty)
3084
}
3185

3286
@Test
33-
func savesURLs() {
34-
store.documentOpened(at: URL(filePath: "Directory/", directoryHint: .isDirectory))
35-
store.documentOpened(at: URL(filePath: "Directory/file.txt", directoryHint: .notDirectory))
36-
37-
let recentURLs = store.recentURLs()
38-
#expect(recentURLs.count == 2)
39-
#expect(recentURLs[0].path(percentEncoded: false) == "Directory/file.txt")
40-
#expect(recentURLs[1].path(percentEncoded: false) == "Directory/")
87+
func savesURLs() throws {
88+
let dir = URL.temp(named: "Directory", directory: true)
89+
let file = URL.temp(named: "Directory/file.txt", directory: false)
90+
91+
try dir.materialise(directory: true)
92+
try file.materialise(directory: false)
93+
94+
RecentsStore.documentOpened(at: dir)
95+
RecentsStore.documentOpened(at: file)
96+
97+
let recents = RecentsStore.recentProjectURLs()
98+
#expect(recents.count == 2)
99+
#expect(recents[0].standardizedFileURL == file.standardizedFileURL)
100+
#expect(recents[1].standardizedFileURL == dir.standardizedFileURL)
41101
}
42102

43103
@Test
44-
func clearURLs() {
45-
store.documentOpened(at: URL(filePath: "Directory/", directoryHint: .isDirectory))
46-
store.documentOpened(at: URL(filePath: "Directory/file.txt", directoryHint: .notDirectory))
104+
func clearURLs() throws {
105+
let dir = URL.temp(named: "Directory", directory: true)
106+
let file = URL.temp(named: "Directory/file.txt", directory: false)
47107

48-
#expect(store.recentURLs().count == 2)
108+
try dir.materialise(directory: true)
109+
try file.materialise(directory: false)
49110

50-
store.clearList()
111+
RecentsStore.documentOpened(at: dir)
112+
RecentsStore.documentOpened(at: file)
113+
#expect(!RecentsStore.recentProjectURLs().isEmpty)
51114

52-
#expect(store.recentURLs().isEmpty)
115+
RecentsStore.clearList()
116+
#expect(RecentsStore.recentProjectURLs().isEmpty)
53117
}
54118

55119
@Test
56-
func duplicatesAreMovedToFront() {
57-
store.documentOpened(at: URL(filePath: "Directory/", directoryHint: .isDirectory))
58-
store.documentOpened(at: URL(filePath: "Directory/file.txt", directoryHint: .notDirectory))
59-
// Move to front
60-
store.documentOpened(at: URL(filePath: "Directory/", directoryHint: .isDirectory))
61-
// Remove duplicate
62-
store.documentOpened(at: URL(filePath: "Directory/", directoryHint: .isDirectory))
63-
64-
let recentURLs = store.recentURLs()
65-
#expect(recentURLs.count == 2)
66-
67-
// Should be moved to the front of the list because it was 'opened' again.
68-
#expect(recentURLs[0].path(percentEncoded: false) == "Directory/")
69-
#expect(recentURLs[1].path(percentEncoded: false) == "Directory/file.txt")
120+
func duplicatesAreMovedToFront() throws {
121+
let dir = URL.temp(named: "Directory", directory: true)
122+
let file = URL.temp(named: "Directory/file.txt", directory: false)
123+
124+
try dir.materialise(directory: true)
125+
try file.materialise(directory: false)
126+
127+
RecentsStore.documentOpened(at: dir)
128+
RecentsStore.documentOpened(at: file)
129+
130+
// Open `dir` again → should move to front
131+
RecentsStore.documentOpened(at: dir)
132+
// Open duplicate again (no change in order, still unique)
133+
RecentsStore.documentOpened(at: dir)
134+
135+
let recents = RecentsStore.recentProjectURLs()
136+
#expect(recents.count == 2)
137+
#expect(recents[0].standardizedFileURL == dir.standardizedFileURL)
138+
#expect(recents[1].standardizedFileURL == file.standardizedFileURL)
70139
}
71140

72141
@Test
73-
func removeSubset() {
74-
store.documentOpened(at: URL(filePath: "Directory/", directoryHint: .isDirectory))
75-
store.documentOpened(at: URL(filePath: "Directory/file.txt", directoryHint: .notDirectory))
142+
func removeSubset() throws {
143+
let dir = URL.temp(named: "Directory", directory: true)
144+
let file = URL.temp(named: "Directory/file.txt", directory: false)
76145

77-
let remaining = store.removeRecentProjects(Set([URL(filePath: "Directory/", directoryHint: .isDirectory)]))
146+
try dir.materialise(directory: true)
147+
try file.materialise(directory: false)
78148

79-
#expect(remaining == [URL(filePath: "Directory/file.txt")])
80-
let recentURLs = store.recentURLs()
81-
#expect(recentURLs.count == 1)
82-
#expect(recentURLs[0].path(percentEncoded: false) == "Directory/file.txt")
149+
RecentsStore.documentOpened(at: dir)
150+
RecentsStore.documentOpened(at: file)
151+
152+
let remaining = RecentsStore.removeRecentProjects([dir])
153+
#expect(remaining == [file])
154+
let recents = RecentsStore.recentProjectURLs()
155+
#expect(recents.count == 1)
156+
#expect(recents[0].standardizedFileURL == file.standardizedFileURL)
83157
}
84158

85159
@Test
86-
func maxesOutAt100Items() {
160+
func maxesOutAt100Items() throws {
87161
for idx in 0..<101 {
88-
store.documentOpened(
89-
at: URL(
90-
filePath: "file\(idx).txt",
91-
directoryHint: Bool.random() ? .isDirectory : .notDirectory
92-
)
93-
)
162+
let isDir = Bool.random()
163+
let name = "entry_\(idx)" + (isDir ? "" : ".txt")
164+
let url = URL.temp(named: name, directory: isDir)
165+
try url.materialise(directory: isDir)
166+
RecentsStore.documentOpened(at: url)
94167
}
95-
96-
#expect(store.recentURLs().count == 100)
168+
#expect(RecentsStore.recentProjectURLs().count == 100)
97169
}
98170
}

0 commit comments

Comments
 (0)