Skip to content

Commit 57383bf

Browse files
committed
test(options): improve test coverage and type safety
WHAT: - Add comprehensive test coverage for complex option values and edge cases - Add tests for terminal features edge cases including empty/malformed features - Add tests for style validation and error handling - Fix type safety issues in terminal features tests WHY: - Ensure proper handling of tmux's complex option types: * Empty feature lists (tmux returns [''] not []) * Malformed feature strings with colons * Features containing spaces and special chars - Improve type safety by: * Adding proper type assertions for runtime checks * Using t.cast() to handle complex union types * Fixing string vs int indexing for SparseArray - Make tests more maintainable by: * Breaking complex assertions into steps * Using descriptive variable names * Adding clear comments about tmux behavior
1 parent 73dd13c commit 57383bf

File tree

1 file changed

+126
-0
lines changed

1 file changed

+126
-0
lines changed

tests/test_options.py

+126
Original file line numberDiff line numberDiff line change
@@ -511,3 +511,129 @@ def test_high_level_api_expectations(server: Server) -> None:
511511
# used that behaves like a list but allows for sparse indexes so the indices
512512
# aren't lost but the shape is still respected.
513513
# 3. Python Typings: Should cast the fully structured objects into types
514+
515+
516+
def test_complex_option_values(server: Server) -> None:
517+
"""Test complex option values and edge cases."""
518+
session = server.new_session(session_name="test")
519+
520+
# Test quoted values with spaces
521+
session.set_option("@complex-option", "value with spaces")
522+
assert session.show_option("@complex-option") == "value with spaces"
523+
524+
# Test escaped characters
525+
session.set_option("@escaped-option", "line1\\nline2")
526+
assert session.show_option("@escaped-option") == "line1\\nline2"
527+
528+
# Test empty values
529+
session.set_option("@empty-option", "")
530+
assert session.show_option("@empty-option") == ""
531+
532+
# Test option inheritance
533+
parent_val = session.show_option("status-style")
534+
session.set_option("status-style", "fg=red")
535+
assert session.show_option("status-style") == "fg=red"
536+
assert session.show_option("status-style", include_inherited=True) == "fg=red"
537+
session.unset_option("status-style")
538+
assert session.show_option("status-style", include_inherited=True) == parent_val
539+
540+
541+
def test_terminal_features_edge_cases(
542+
server: Server,
543+
monkeypatch: pytest.MonkeyPatch,
544+
) -> None:
545+
"""Test edge cases for terminal-features option."""
546+
# Test empty features
547+
monkeypatch.setattr(
548+
server,
549+
"cmd",
550+
fake_cmd(stdout=["terminal-features[0] xterm*:"]),
551+
)
552+
options = server._show_options()
553+
terminal_features = t.cast(dict[str, list[str]], options["terminal-features"])
554+
assert isinstance(terminal_features, dict)
555+
xterm_features = terminal_features["xterm*"]
556+
assert isinstance(xterm_features, list)
557+
assert xterm_features == [""] # tmux returns [''] for empty features
558+
559+
# Test malformed features
560+
monkeypatch.setattr(
561+
server,
562+
"cmd",
563+
fake_cmd(stdout=["terminal-features[0] xterm*:invalid:feature:with:colons"]),
564+
)
565+
options = server._show_options()
566+
terminal_features = t.cast(dict[str, list[str]], options["terminal-features"])
567+
assert isinstance(terminal_features, dict)
568+
xterm_features = terminal_features["xterm*"]
569+
assert isinstance(xterm_features, list)
570+
assert any(f == "invalid" for f in xterm_features)
571+
assert any(f == "feature" for f in xterm_features)
572+
573+
# Test features with special characters
574+
monkeypatch.setattr(
575+
server,
576+
"cmd",
577+
fake_cmd(
578+
stdout=[
579+
'terminal-features[0] "xterm*:feature with space:special*char"',
580+
],
581+
),
582+
)
583+
options = server._show_options()
584+
terminal_features = t.cast(dict[str, list[str]], options["terminal-features"])
585+
assert isinstance(terminal_features, dict)
586+
xterm_features = terminal_features["xterm*"]
587+
assert isinstance(xterm_features, list)
588+
assert any(f == "feature with space" for f in xterm_features)
589+
assert any(f == "special*char" for f in xterm_features)
590+
591+
592+
def test_style_option_validation(server: Server) -> None:
593+
"""Test style option validation."""
594+
session = server.new_session(session_name="test")
595+
596+
# Valid style
597+
session.set_option("status-style", "fg=red,bg=default,bold")
598+
assert session.show_option("status-style") == "fg=red,bg=default,bold"
599+
600+
# Invalid style should raise OptionError
601+
with pytest.raises(OptionError):
602+
session.set_option("status-style", "invalid-style")
603+
604+
# Test complex style with multiple attributes
605+
session.set_option(
606+
"status-style",
607+
"fg=colour240,bg=#525252,bold,underscore",
608+
)
609+
assert (
610+
session.show_option("status-style") == "fg=colour240,bg=#525252,bold,underscore"
611+
)
612+
613+
# Test style with variables
614+
session.set_option("status-style", "fg=#{?pane_in_mode,red,green}")
615+
assert session.show_option("status-style") == "fg=#{?pane_in_mode,red,green}"
616+
617+
618+
def test_option_error_handling(server: Server) -> None:
619+
"""Test error handling for options."""
620+
session = server.new_session(session_name="test")
621+
622+
# Test invalid/unknown option (tmux 3.0+ returns 'invalid option')
623+
with pytest.raises(OptionError) as exc_info:
624+
session.show_option("non-existent-option")
625+
error_msg = str(exc_info.value).lower()
626+
assert any(msg in error_msg for msg in ["unknown option", "invalid option"])
627+
628+
# Test invalid option value
629+
with pytest.raises(OptionError):
630+
session.set_option("aggressive-resize", "invalid")
631+
632+
# Test ambiguous option (if supported by tmux version)
633+
if has_gte_version("2.4"):
634+
with pytest.raises(OptionError) as exc_info:
635+
# Use a partial name that could match multiple options
636+
session.show_option(
637+
"window-"
638+
) # Ambiguous: could be window-size, window-style, etc.
639+
assert "ambiguous option" in str(exc_info.value).lower()

0 commit comments

Comments
 (0)