Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 103 additions & 5 deletions specs/file/watcher.t27
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ module FileWatcher {
// ════════════════════════════════════════════════════════════════════

// WatcherID is a branded string representing a watcher identifier
struct WatcherID(str);
struct WatcherID {
// Placeholder for branded string type
}

// ════════════════════════════════════════════════════════════════════
// Watcher Operations
Expand Down Expand Up @@ -143,12 +145,26 @@ module FileWatcher {

// watch_batch watches multiple paths at once
fn watch_batch(watcherID: WatcherID, paths: [str], recursive: bool) -> Result<void, FileError> {
// Implementation: Watch multiple paths
// Watch each path individually
for (paths) |path| {
var result = watch(watcherID, path, recursive);
if (result != Ok()) {
return result;
}
}
return Ok();
}

// unwatch_batch stops watching multiple paths
fn unwatch_batch(watcherID: WatcherID, paths: [str]) -> Result<void, FileError> {
// Implementation: Stop watching multiple paths
// Unwatch each path individually
for (paths) |path| {
var result = unwatch(watcherID, path);
if (result != Ok()) {
return result;
}
}
return Ok();
}

// ════════════════════════════════════════════════════════════════════
Expand All @@ -166,12 +182,40 @@ module FileWatcher {

// get_stats returns watcher statistics
fn get_stats(watcherID: WatcherID) -> Result<WatcherStats, FileError> {
// Implementation: Get watcher statistics
// Get current watched paths count
var watchedPaths = get_watched_paths(watcherID);
if (watchedPaths != Ok()) {
return watchedPaths;
}

// Get current system time for statistics
var currentTime = std.time.timestamp();

var stats = WatcherStats {
paths = watchedPaths.len,
events = 0, // Events would be tracked in actual implementation
errors = 0, // Errors would be tracked in actual implementation
startTime = currentTime, // Would be actual start time in real implementation
lastEvent = null, // Would track last event timestamp in real implementation
};
return Ok(stats);
}

// reset_stats resets watcher statistics
fn reset_stats(watcherID: WatcherID) -> Result<void, FileError> {
// Implementation: Reset event/error counters
// In a real implementation, this would reset internal statistics tracking
// For now, we'll validate the watcher exists and return success
var active = is_active(watcherID);
if (active != Ok()) {
return active;
}

// If watcher is not active, return an error
if (!active) {
return Err(FileError.InvalidPath);
}

return Ok();
}

// ════════════════════════════════════════════════════════════════════
Expand Down Expand Up @@ -547,4 +591,58 @@ module FileWatcher {
assert(stats.errors == 5);
assert(stats.lastEvent == null);
}

test "watch_batch_multiple_paths" {
var id = WatcherID("test-watcher");
var paths = ["/tmp/test1", "/tmp/test2"];
var result = watch_batch(id, paths, true);
assert(result == Ok());

// Verify that paths are now being watched
var watchedPaths = get_watched_paths(id);
assert(watchedPaths == Ok());
// Note: Actual path count depends on implementation details
}

test "unwatch_batch_multiple_paths" {
var id = WatcherID("test-watcher");
var paths = ["/tmp/test1", "/tmp/test2"];

// First watch the paths, then unwatch them
var watchResult = watch_batch(id, paths, false);
assert(watchResult == Ok());

var unwatchResult = unwatch_batch(id, paths);
assert(unwatchResult == Ok());
}

test "get_stats_empty_watcher" {
var id = WatcherID("test-watcher");
var result = get_stats(id);
assert(result == Ok());

var stats = result.unwrap();
// For an empty watcher, paths should be 0
assert(stats.paths == 0);
// Events and errors should be 0 for new watcher
assert(stats.events == 0);
assert(stats.errors == 0);
// Start time should be set (current timestamp)
assert(stats.startTime > 0);
// Last event should be null for new watcher
assert(stats.lastEvent == null);
}

test "reset_stats_success" {
var id = WatcherID("test-watcher");
var result = reset_stats(id);
assert(result == Ok());

// Test that reset works on an active watcher
var watchResult = watch(id, "/tmp/test", false);
assert(watchResult == Ok());

var resetResult = reset_stats(id);
assert(resetResult == Ok());
}
}
Loading