test(coverage): backfill WS edge cases and small auth/type/config branches#134
Conversation
Code Review — PR #134: Backfill WS edge cases and small auth/type/config branchesOverall: LGTM. This is clean, focused coverage work with no production-code changes. The sleep→Event conversions are a genuine quality improvement. A few minor items below. What the PR does
Positives
Minor / Nits1. Multi-paragraph docstrings in
def test_non_string_bool_element_raises_unhelpful_type_error(self) -> None:
# Pins crash path: bool fails "," in elem check; update if validation is added.
with pytest.raises(TypeError, match=r"argument of type 'bool' is not iterable"):
_join_tickers([True, "A"]) # type: ignore[list-item]2. Module-level docstring in Nine lines for what could be two. The key facts (TypeError propagates unwrapped, lines 27/60 are the branches) are worth keeping, but the "Note:" paragraph restates what the test names already say. Same CLAUDE.md guideline. 3. Reaching into 4. Insertion-order assumption in sids = [sub.server_sid for sub in session._sub_mgr.active_subscriptions.values()]
sid_a, sid_b = sids[0], sids[1]This relies on dict insertion order (guaranteed in Python 3.7+, project requires 3.12, so it's safe). Still, if the test starts flapping, this is the first place to look. No issues found in
SummaryThe sleep→Event conversion alone justifies this PR. The new coverage is accurate and the tricky behavioral deviations (Pydantic TypeError, |
|
Addressed:
Acknowledged (informational only, no change):
|
Per bot review on #134: - test_non_string_bool_element_raises_unhelpful_type_error: 6-line docstring -> 1-line inline comment. The WHY (pin crash path so a future fix trips this test) survives without the prose. - test_types.py module docstring: 9 lines -> 1 line. The Pydantic- BeforeValidator-doesn't-wrap note was redundant with the test names. Skipped: - test_non_string_int_element docstring is already one line; no change. - session._sub_mgr access + insertion-order assumption are flagged as informational by bot, not requested changes. uv run pytest tests/test_base_helpers.py tests/test_types.py -q: 22 passed. ruff clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Code Review — PR #134: test(coverage): backfill WS edge cases and small auth/type/config branchesOverall: Approve with minor notes. This is a well-scoped, test-only PR. The What's Working Well
Minor Concerns1. Crash-path tests pin known-bad behavior ( def test_non_string_bool_element_raises_unhelpful_type_error(self) -> None:
# Pins crash path: bool fails `"," in elem` check; update if validation is added.
with pytest.raises(TypeError, match=r"argument of type 'bool' is not iterable"):
_join_tickers([True, "A"])Asserting that 2. Accessing sids = [
sub.server_sid
for sub in session._sub_mgr.active_subscriptions.values()
]This reaches into a private attribute to verify internal subscription tracking. It works, and for this kind of structural assertion there's not always a better option. One alternative: assert only on observable behavior (both iterators yield the correct messages, already done below), and drop the 3.
4. assert len(sids) == 2
assert sids[0] != sids[1]
sid_a, sid_b = sids[0], sids[1]
assert sid_a is not None and sid_b is not None # this line
No Issues Found
Summary
Ready to merge after addressing the nit on the vacuous 🤖 Generated with Claude Code |
…nches Closes the test-coverage gaps from the Wave 5 audit: - F-Q-09: pin KalshiAuth.from_key_path PermissionError and passphrase-protected key branches (both surface helpful KalshiAuthError messages). - F-Q-10: pin DollarDecimal / FixedPointCount TypeError fallback for unexpected input types (list, dict). Raw TypeError surfaces with the offending type name. - F-Q-12: pin KalshiClient.is_authenticated / AsyncKalshiClient.is_authenticated true/false branches with and without auth. - F-Q-13: replace flaky `await asyncio.sleep(0.2-0.3); assert` patterns in ws/test_client.py and ws/test_integration.py with deterministic `asyncio.Event` + `asyncio.wait_for(timeout=2.0)` waits. Callbacks signal completion; tests no longer race the event loop. - F-Q-15: cover two subs to the same channel (orderbook_delta) with different tickers - distinct server_sids, distinct iterators, message-to-sid routing. - F-Q-16: pin current `_join_tickers` behavior for non-string list elements (bool, int) - existing crash with `argument of type 'X' is not iterable` is captured so any future validation upgrade trips a test. - F-Q-18: cover ws/client.py:197-203 sentinel-broadcast on permanent reconnect failure. Force ws_max_retries=1 + reject_auth=True after first disconnect; assert the iterator exits via StopAsyncIteration instead of hanging. All changes are test-only. Net: +10 tests (1612 -> 1622). Wave 3's WS recv-loop, dispatcher, and orderbook are unchanged - this only adds tests around them. Closes #102 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per bot review on #134: - test_non_string_bool_element_raises_unhelpful_type_error: 6-line docstring -> 1-line inline comment. The WHY (pin crash path so a future fix trips this test) survives without the prose. - test_types.py module docstring: 9 lines -> 1 line. The Pydantic- BeforeValidator-doesn't-wrap note was redundant with the test names. Skipped: - test_non_string_int_element docstring is already one line; no change. - session._sub_mgr access + insertion-order assumption are flagged as informational by bot, not requested changes. uv run pytest tests/test_base_helpers.py tests/test_types.py -q: 22 passed. ruff clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6e9d00b to
4bac83c
Compare
Code Review — PR #134 (Wave 2 Coverage: WS edge cases, auth, types, base helpers)Overall this is a clean, well-scoped wave of coverage tests. The Issues1. Potential sid-ordering assumption in
|
Summary
Wave 2 #102: closes the umbrella audit-Q backlog covering 7 small coverage gaps across WS edge cases, auth, type validators, and small base-helper branches.
+10 tests across 7 files:
tests/test_auth.pyPermissionErroron unreadable key, encrypted-PEM passphrase pathtests/test_types.py(new)DollarDecimalBeforeValidatorraisesTypeErrorfor non-coercible inputstests/test_client.py+test_async_client.pytests/ws/test_client.py+test_integration.pyasyncio.Eventtests/ws/test_integration.pysubscribe_orderbook_deltawith different tickers, distinct sids viasession._sub_mgr.active_subscriptionstests/test_base_helpers.pyboolandintmistypestests/ws/test_integration.pyStopAsyncIterationwithin timeoutNotes
BeforeValidatordoes NOT wrap a non-ValueErrorexception inValidationError— theTypeErrorpropagates raw. Tests assertTypeErrordirectly. Issue body's mention ofValidationErrorwrapping was incorrect for current Pydantic behavior.kalshi/ws/{client,dispatch,orderbook,channels}.py.Closes #102
Test plan
uv run ruff check .cleanuv run mypy kalshi/clean (strict)