1
0
mirror of https://github.com/nicoverbruggen/phpmon.git synced 2026-04-02 01:30:07 +02:00

Improve FSNotifierTest

This commit is contained in:
2025-11-29 23:27:02 +01:00
parent e968263568
commit 22c46e7e85

View File

@@ -11,37 +11,33 @@ import Foundation
@Suite(.serialized) @Suite(.serialized)
struct FSNotifierTest { struct FSNotifierTest {
/**
This test verifies that FSNotifier fires the onChange callback when a file is modified. @Test func notifier_fires_when_file_is_modified() async throws {
*/
@Test func notifier_fires_when_file_is_modified_and_debounces_correctly() async throws {
// Create a temporary file to monitor // Create a temporary file to monitor
let tempDir = FileManager.default.temporaryDirectory let tempDir = FileManager.default.temporaryDirectory
let testFile = tempDir.appendingPathComponent("fs_notifier_test_\(UUID().uuidString).txt") let testFile = tempDir.appendingPathComponent("fs_notifier_test_\(UUID().uuidString).txt")
FileManager.default.createFile(atPath: testFile.path, contents: nil) FileManager.default.createFile(atPath: testFile.path, contents: nil)
defer { // Our variable to keep track of
try? FileManager.default.removeItem(at: testFile)
}
let eventFired = Locked<Int>(0) let eventFired = Locked<Int>(0)
// Our debouncer
let debouncer = Debouncer() let debouncer = Debouncer()
// Create notifier // Set up the notifier
let notifier = FSNotifier( let notifier = FSNotifier(for: testFile, eventMask: .write, onChange: {
for: testFile, Task { await debouncer.debounce(for: 1.0) {
eventMask: .write, eventFired.value += 1
onChange: { }}
Task { })
// Debouncer is an actor so this is allowed
await debouncer.debounce(for: 1.0) {
eventFired.value += 1
}
}
}
)
// Modify the file, twice // Cleanup for later
defer {
try? FileManager.default.removeItem(at: testFile)
notifier.terminate()
}
// Modify the file, twice, debounce should work
try "hello".write(to: testFile, atomically: false, encoding: .utf8) try "hello".write(to: testFile, atomically: false, encoding: .utf8)
try "hello".write(to: testFile, atomically: false, encoding: .utf8) try "hello".write(to: testFile, atomically: false, encoding: .utf8)
@@ -55,8 +51,52 @@ struct FSNotifierTest {
// Verify after another second, our second write is actually noted // Verify after another second, our second write is actually noted
await delay(seconds: 1.2) await delay(seconds: 1.2)
#expect(eventFired.value == 2) #expect(eventFired.value == 2)
}
// Clean up notifier @Test func notifier_suspends_and_resumes_correctly() async throws {
notifier.terminate() // Create a temporary file to monitor
let tempDir = FileManager.default.temporaryDirectory
let testFile = tempDir.appendingPathComponent("fs_notifier_test_\(UUID().uuidString).txt")
FileManager.default.createFile(atPath: testFile.path, contents: nil)
// Our variable to keep track of
let eventFired = Locked<Int>(0)
// Create notifier
let notifier = FSNotifier(for: testFile, eventMask: .write, onChange: {
Task { eventFired.value += 1 }
})
// Cleanup for later
defer {
try? FileManager.default.removeItem(at: testFile)
notifier.terminate()
}
// Modify the file, twice
try "hello".write(to: testFile, atomically: false, encoding: .utf8)
await delay(seconds: 0.2)
#expect(eventFired.value == 1)
// Try to write again (after debounce timing)
try "hello".write(to: testFile, atomically: false, encoding: .utf8)
await delay(seconds: 0.2)
#expect(eventFired.value == 2)
// Now, we will suspend
await notifier.suspend()
// Despite writing to the file, our event did not fire
try "hello".write(to: testFile, atomically: false, encoding: .utf8)
await delay(seconds: 0.2)
#expect(eventFired.value == 2)
// Now, we will resume
await notifier.resume()
// Our event should have fired again
try "hello".write(to: testFile, atomically: false, encoding: .utf8)
await delay(seconds: 0.2)
#expect(eventFired.value == 3)
} }
} }