Skip to content

Commit fa12f04

Browse files
committed
tests(hooks): add comprehensive tests for bulk operations API
why: Ensure bulk operations work correctly across all input types what: - Add TestBulkOperationsAPI class with 15 tests - Test get_hook_indices with empty, sequential, and sparse indices - Test get_hook_values with empty and populated hooks - Test set_hooks_bulk with dict, list, and SparseArray inputs - Test clear_hook and append_hook behavior - Test method chaining support
1 parent 953e3f3 commit fa12f04

File tree

1 file changed

+274
-0
lines changed

1 file changed

+274
-0
lines changed

tests/test_hooks.py

Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,3 +525,277 @@ def test_new_hooks_version_gated(server: Server, test_case: HookTestCase) -> Non
525525

526526
# Cleanup
527527
session.unset_hook(f"{test_case.hook}[0]")
528+
529+
530+
# =============================================================================
531+
# Bulk Operations API Tests
532+
# =============================================================================
533+
534+
535+
class TestBulkOperationsAPI:
536+
"""Tests for hook bulk operations API."""
537+
538+
def test_get_hook_indices_empty(self, server: Server) -> None:
539+
"""Test get_hook_indices returns empty list when no hooks set."""
540+
session = server.new_session(session_name="test_bulk_ops")
541+
542+
indices = session.get_hook_indices("session-renamed")
543+
assert indices == []
544+
545+
def test_get_hook_indices_sequential(self, server: Server) -> None:
546+
"""Test get_hook_indices with sequential indices."""
547+
session = server.new_session(session_name="test_bulk_ops")
548+
549+
# Set hooks at indices 0, 1, 2
550+
session.set_hook("session-renamed[0]", "display-message 'hook 0'")
551+
session.set_hook("session-renamed[1]", "display-message 'hook 1'")
552+
session.set_hook("session-renamed[2]", "display-message 'hook 2'")
553+
554+
indices = session.get_hook_indices("session-renamed")
555+
assert indices == [0, 1, 2]
556+
557+
# Cleanup
558+
session.clear_hook("session-renamed")
559+
560+
def test_get_hook_indices_sparse(self, server: Server) -> None:
561+
"""Test get_hook_indices with sparse (non-sequential) indices."""
562+
session = server.new_session(session_name="test_bulk_ops")
563+
564+
# Set hooks at non-sequential indices
565+
session.set_hook("session-renamed[0]", "display-message 'hook 0'")
566+
session.set_hook("session-renamed[5]", "display-message 'hook 5'")
567+
session.set_hook("session-renamed[10]", "display-message 'hook 10'")
568+
569+
indices = session.get_hook_indices("session-renamed")
570+
assert indices == [0, 5, 10]
571+
572+
# Cleanup
573+
session.clear_hook("session-renamed")
574+
575+
def test_get_hook_values_empty(self, server: Server) -> None:
576+
"""Test get_hook_values returns empty SparseArray when no hooks set."""
577+
session = server.new_session(session_name="test_bulk_ops")
578+
579+
values = session.get_hook_values("session-renamed")
580+
assert isinstance(values, SparseArray)
581+
assert len(values) == 0
582+
assert values.as_list() == []
583+
584+
def test_get_hook_values(self, server: Server) -> None:
585+
"""Test get_hook_values returns SparseArray with correct values."""
586+
session = server.new_session(session_name="test_bulk_ops")
587+
588+
# Set hooks
589+
session.set_hook("session-renamed[0]", "display-message 'hook 0'")
590+
session.set_hook("session-renamed[5]", "display-message 'hook 5'")
591+
592+
values = session.get_hook_values("session-renamed")
593+
assert isinstance(values, SparseArray)
594+
assert 0 in values
595+
assert 5 in values
596+
assert 3 not in values
597+
assert "display-message" in values[0]
598+
assert "display-message" in values[5]
599+
600+
# Cleanup
601+
session.clear_hook("session-renamed")
602+
603+
def test_get_hook_values_iter(self, server: Server) -> None:
604+
"""Test iterating over hook values in sorted order."""
605+
session = server.new_session(session_name="test_bulk_ops")
606+
607+
# Set hooks at sparse indices
608+
session.set_hook("session-renamed[5]", "display-message 'fifth'")
609+
session.set_hook("session-renamed[0]", "display-message 'zeroth'")
610+
session.set_hook("session-renamed[2]", "display-message 'second'")
611+
612+
values = session.get_hook_values("session-renamed")
613+
value_list = list(values.iter_values())
614+
615+
# Values should be in sorted index order
616+
assert len(value_list) == 3
617+
assert "zeroth" in value_list[0]
618+
assert "second" in value_list[1]
619+
assert "fifth" in value_list[2]
620+
621+
# Cleanup
622+
session.clear_hook("session-renamed")
623+
624+
def test_set_hooks_bulk_with_dict(self, server: Server) -> None:
625+
"""Test set_hooks_bulk with explicit index dict."""
626+
session = server.new_session(session_name="test_bulk_ops")
627+
628+
session.set_hooks_bulk(
629+
"session-renamed",
630+
{
631+
0: "display-message 'hook 0'",
632+
1: "display-message 'hook 1'",
633+
5: "display-message 'hook 5'",
634+
},
635+
)
636+
637+
indices = session.get_hook_indices("session-renamed")
638+
assert indices == [0, 1, 5]
639+
640+
values = session.get_hook_values("session-renamed")
641+
assert "hook 0" in values[0]
642+
assert "hook 1" in values[1]
643+
assert "hook 5" in values[5]
644+
645+
# Cleanup
646+
session.clear_hook("session-renamed")
647+
648+
def test_set_hooks_bulk_with_list(self, server: Server) -> None:
649+
"""Test set_hooks_bulk with list (sequential indices)."""
650+
session = server.new_session(session_name="test_bulk_ops")
651+
652+
session.set_hooks_bulk(
653+
"session-renamed",
654+
[
655+
"display-message 'hook 0'",
656+
"display-message 'hook 1'",
657+
"display-message 'hook 2'",
658+
],
659+
)
660+
661+
indices = session.get_hook_indices("session-renamed")
662+
assert indices == [0, 1, 2]
663+
664+
# Cleanup
665+
session.clear_hook("session-renamed")
666+
667+
def test_set_hooks_bulk_with_sparse_array(self, server: Server) -> None:
668+
"""Test set_hooks_bulk with SparseArray."""
669+
session = server.new_session(session_name="test_bulk_ops")
670+
671+
sparse: SparseArray[str] = SparseArray()
672+
sparse.add(0, "display-message 'from sparse 0'")
673+
sparse.add(10, "display-message 'from sparse 10'")
674+
675+
session.set_hooks_bulk("session-renamed", sparse)
676+
677+
indices = session.get_hook_indices("session-renamed")
678+
assert indices == [0, 10]
679+
680+
# Cleanup
681+
session.clear_hook("session-renamed")
682+
683+
def test_set_hooks_bulk_clear_existing(self, server: Server) -> None:
684+
"""Test set_hooks_bulk with clear_existing=True."""
685+
session = server.new_session(session_name="test_bulk_ops")
686+
687+
# Set initial hooks
688+
session.set_hooks_bulk(
689+
"session-renamed",
690+
{0: "display-message 'old 0'", 1: "display-message 'old 1'"},
691+
)
692+
693+
# Replace with new hooks
694+
session.set_hooks_bulk(
695+
"session-renamed",
696+
{0: "display-message 'new 0'"},
697+
clear_existing=True,
698+
)
699+
700+
indices = session.get_hook_indices("session-renamed")
701+
assert indices == [0]
702+
703+
values = session.get_hook_values("session-renamed")
704+
assert "new 0" in values[0]
705+
706+
# Cleanup
707+
session.clear_hook("session-renamed")
708+
709+
def test_clear_hook(self, server: Server) -> None:
710+
"""Test clear_hook removes all indexed values."""
711+
session = server.new_session(session_name="test_bulk_ops")
712+
713+
# Set multiple hooks
714+
session.set_hooks_bulk(
715+
"session-renamed",
716+
{0: "display-message 'hook 0'", 5: "display-message 'hook 5'"},
717+
)
718+
719+
# Verify they exist
720+
assert session.get_hook_indices("session-renamed") == [0, 5]
721+
722+
# Clear all
723+
session.clear_hook("session-renamed")
724+
725+
# Verify cleared
726+
assert session.get_hook_indices("session-renamed") == []
727+
728+
def test_append_hook_to_empty(self, server: Server) -> None:
729+
"""Test append_hook when no hooks exist (starts at index 0)."""
730+
session = server.new_session(session_name="test_bulk_ops")
731+
732+
session.append_hook("session-renamed", "display-message 'appended'")
733+
734+
indices = session.get_hook_indices("session-renamed")
735+
assert indices == [0]
736+
737+
values = session.get_hook_values("session-renamed")
738+
assert "appended" in values[0]
739+
740+
# Cleanup
741+
session.clear_hook("session-renamed")
742+
743+
def test_append_hook_sequential(self, server: Server) -> None:
744+
"""Test append_hook adds at next sequential index."""
745+
session = server.new_session(session_name="test_bulk_ops")
746+
747+
# Set initial hook
748+
session.set_hook("session-renamed[0]", "display-message 'initial'")
749+
750+
# Append
751+
session.append_hook("session-renamed", "display-message 'appended'")
752+
753+
indices = session.get_hook_indices("session-renamed")
754+
assert indices == [0, 1]
755+
756+
# Cleanup
757+
session.clear_hook("session-renamed")
758+
759+
def test_append_hook_after_sparse(self, server: Server) -> None:
760+
"""Test append_hook adds at max+1 even with sparse indices."""
761+
session = server.new_session(session_name="test_bulk_ops")
762+
763+
# Set hooks at sparse indices
764+
session.set_hook("session-renamed[0]", "display-message 'at 0'")
765+
session.set_hook("session-renamed[10]", "display-message 'at 10'")
766+
767+
# Append should be at index 11
768+
session.append_hook("session-renamed", "display-message 'appended'")
769+
770+
indices = session.get_hook_indices("session-renamed")
771+
assert indices == [0, 10, 11]
772+
773+
values = session.get_hook_values("session-renamed")
774+
assert "appended" in values[11]
775+
776+
# Cleanup
777+
session.clear_hook("session-renamed")
778+
779+
def test_method_chaining(self, server: Server) -> None:
780+
"""Test that bulk operations support method chaining."""
781+
session = server.new_session(session_name="test_bulk_ops")
782+
783+
# Chain operations
784+
result = (
785+
session.set_hooks_bulk(
786+
"session-renamed",
787+
["display-message 'hook 0'"],
788+
)
789+
.append_hook("session-renamed", "display-message 'hook 1'")
790+
.append_hook("session-renamed", "display-message 'hook 2'")
791+
)
792+
793+
# Should return the session
794+
assert result is session
795+
796+
# Verify all hooks set
797+
indices = session.get_hook_indices("session-renamed")
798+
assert indices == [0, 1, 2]
799+
800+
# Cleanup
801+
session.clear_hook("session-renamed")

0 commit comments

Comments
 (0)