diff --git a/test/TestHeapq.fs b/test/TestHeapq.fs index d0dd22d..9ac7f97 100644 --- a/test/TestHeapq.fs +++ b/test/TestHeapq.fs @@ -37,3 +37,23 @@ let ``test nlargest works`` () = let ``test nsmallest works`` () = let result = heapq.nsmallest (3, [ 1; 5; 2; 8; 3; 7 ]) result |> equal (ResizeArray [ 1; 2; 3 ]) + +[] +let ``test heapreplace pops smallest and pushes new item`` () = + let heap = ResizeArray [ 1; 3; 5; 7 ] + heapq.heapify heap + // Replace root (1) with 4; returns old root (1) + heapq.heapreplace (heap, 4) |> equal 1 + // Smallest is now 3 + heapq.heappop heap |> equal 3 + +[] +let ``test heapreplace with larger item maintains heap`` () = + let heap = ResizeArray [ 2; 6; 10 ] + heapq.heapify heap + // Replace root (2) with 8; returns old root (2) + heapq.heapreplace (heap, 8) |> equal 2 + // Remaining heap elements sorted: 6, 8, 10 + heapq.heappop heap |> equal 6 + heapq.heappop heap |> equal 8 + heapq.heappop heap |> equal 10 diff --git a/test/TestThreading.fs b/test/TestThreading.fs index 80d14ca..33fad23 100644 --- a/test/TestThreading.fs +++ b/test/TestThreading.fs @@ -18,3 +18,128 @@ let ``test local creates thread-local storage`` () = let local = threading.local () setattr local "value" 42 getattr local "value" 0 |> equal 42 + +// ============================================================================ +// Lock tests +// ============================================================================ + +[] +let ``test Lock acquire and release work`` () = + let lock = Lock() + let acquired = lock.acquire () + acquired |> equal true + lock.release () + +[] +let ``test Lock locked reflects state`` () = + let lock = Lock() + lock.locked () |> equal false + lock.acquire () |> ignore + lock.locked () |> equal true + lock.release () + lock.locked () |> equal false + +[] +let ``test Lock acquire non-blocking fails when locked`` () = + let lock = Lock() + lock.acquire () |> ignore + // Non-blocking acquire should fail since lock is already held + let second = lock.acquire (blocking = false) + second |> equal false + lock.release () + +// ============================================================================ +// RLock tests +// ============================================================================ + +[] +let ``test RLock acquire and release work`` () = + let rlock = RLock() + let acquired = rlock.acquire () + acquired |> equal true + rlock.release () + +[] +let ``test RLock is reentrant`` () = + let rlock = RLock() + // Same thread can acquire multiple times + rlock.acquire () |> ignore + let second = rlock.acquire () + second |> equal true + rlock.release () + rlock.release () + +// ============================================================================ +// Event tests +// ============================================================================ + +[] +let ``test Event is_set starts false`` () = + let ev = Event() + ev.is_set () |> equal false + +[] +let ``test Event set and clear work`` () = + let ev = Event() + ev.set () + ev.is_set () |> equal true + ev.clear () + ev.is_set () |> equal false + +[] +let ``test Event wait returns true when already set`` () = + let ev = Event() + ev.set () + let result = ev.wait () + result |> equal true + +[] +let ``test Event wait with timeout returns false when not set`` () = + let ev = Event() + // Timeout of 0 seconds — event not set, should return false immediately + let result = ev.wait (timeout = 0.0) + result |> equal false + +// ============================================================================ +// Thread tests +// ============================================================================ + +[] +let ``test Thread runs target function`` () = + let results = ResizeArray() + let t = Thread(target = fun () -> results.Add 42) + t.start () + t.join () + results.Count |> equal 1 + results.[0] |> equal 42 + +[] +let ``test Thread is_alive reflects state`` () = + let ev = Event() + let t = Thread(target = fun () -> ev.wait () |> ignore) + t.is_alive () |> equal false + t.start () + t.is_alive () |> equal true + ev.set () + t.join () + t.is_alive () |> equal false + +[] +let ``test Thread name can be set`` () = + let t = Thread(target = (fun () -> ()), name = "worker") + t.name |> equal "worker" + +[] +let ``test main_thread returns a Thread`` () = + let mt = threading.main_thread () + mt.is_alive () |> equal true + +[] +let ``test current_thread returns a Thread`` () = + let ct = threading.current_thread () + ct.is_alive () |> equal true + +[] +let ``test enumerate returns list with at least one thread`` () = + let threads = threading.enumerate () + (threads.Length >= 1) |> equal true