verifaied 0.34.0.dev84__tar.gz → 0.34.1.dev85__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/PKG-INFO +1 -1
  2. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/pyproject.toml +1 -1
  3. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/record.py +13 -2
  4. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_record.py +40 -16
  5. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/uv.lock +1 -1
  6. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/.gitignore +0 -0
  7. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/LICENSE +0 -0
  8. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/README.md +0 -0
  9. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/__init__.py +0 -0
  10. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/__main__.py +0 -0
  11. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/agent_mcp.py +0 -0
  12. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/agent_steps.py +0 -0
  13. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/analyzer.py +0 -0
  14. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/audit.py +0 -0
  15. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/cli.py +0 -0
  16. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/client.py +0 -0
  17. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/collect_browser.js +0 -0
  18. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/collect_browser.py +0 -0
  19. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/config.py +0 -0
  20. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/failure_text.py +0 -0
  21. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/finishing.py +0 -0
  22. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/instrument.py +0 -0
  23. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/instrument_snippets.py +0 -0
  24. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/instrumenter.js +0 -0
  25. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/instrumenter.py +0 -0
  26. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/lanes.py +0 -0
  27. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/prompts.py +0 -0
  28. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/proxy.py +0 -0
  29. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/recorder_driver.js +0 -0
  30. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/recorder_observer.js +0 -0
  31. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/recorder_picker.js +0 -0
  32. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/recorder_refs.js +0 -0
  33. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/recorder_spec.js +0 -0
  34. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/replay_harvest.ts +0 -0
  35. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/repo_config.py +0 -0
  36. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/run_reporter.js +0 -0
  37. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/runner_dir.py +0 -0
  38. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/skill/SKILL.md +0 -0
  39. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/skill/reference/commands.md +0 -0
  40. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/skillcmd.py +0 -0
  41. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/source_index.py +0 -0
  42. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/stepcheck.py +0 -0
  43. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/subprocess_util.py +0 -0
  44. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/suite_report.py +0 -0
  45. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/testcmd.py +0 -0
  46. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/uploader.py +0 -0
  47. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/varcmd.py +0 -0
  48. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/video_render.js +0 -0
  49. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/src/verifaied/video_render.py +0 -0
  50. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/__init__.py +0 -0
  51. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/conftest.py +0 -0
  52. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_agent_mcp.py +0 -0
  53. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_audit.py +0 -0
  54. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_browser_settings_parity.py +0 -0
  55. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_caption_parity.py +0 -0
  56. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_check.py +0 -0
  57. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_check_done.py +0 -0
  58. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_clear_manual.py +0 -0
  59. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_cli.py +0 -0
  60. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_client.py +0 -0
  61. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_collect_browser.py +0 -0
  62. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_config.py +0 -0
  63. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_console_label_parity.py +0 -0
  64. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_finishing.py +0 -0
  65. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_instrument.py +0 -0
  66. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_instrument_detect.py +0 -0
  67. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_instrument_snippets.py +0 -0
  68. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_instrumenter.py +0 -0
  69. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_lanes.py +0 -0
  70. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_pause_parity.py +0 -0
  71. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_prompt_parity.py +0 -0
  72. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_proxy.py +0 -0
  73. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_render_parity.py +0 -0
  74. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_replay_harvest_runner.py +0 -0
  75. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_repo_config.py +0 -0
  76. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_skill_parity.py +0 -0
  77. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_skillcmd.py +0 -0
  78. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_source_index.py +0 -0
  79. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_stepcheck_parity.py +0 -0
  80. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_suite_report.py +0 -0
  81. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_testcmd.py +0 -0
  82. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_uploader.py +0 -0
  83. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_varcmd.py +0 -0
  84. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_video_render.py +0 -0
  85. {verifaied-0.34.0.dev84 → verifaied-0.34.1.dev85}/tests/test_video_render_runner.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: verifaied
3
- Version: 0.34.0.dev84
3
+ Version: 0.34.1.dev85
4
4
  Summary: Find what's untested in your code — locally, no account required
5
5
  Project-URL: Homepage, https://pypi.org/project/verifaied/
6
6
  Author: Kyle Richards
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "verifaied"
3
- version = "0.34.0.dev84"
3
+ version = "0.34.1.dev85"
4
4
  description = "Find what's untested in your code — locally, no account required"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -774,6 +774,17 @@ def _final_flush(
774
774
  return True
775
775
 
776
776
 
777
+ def _sleep(seconds: float) -> None:
778
+ """The session loop's own clock.
779
+
780
+ Its own name rather than ``time.sleep`` so a test can script it without
781
+ scripting every other sleep in the process — ``subprocess`` polls a
782
+ child it waits on with ``time.sleep``, and so does anything else
783
+ running beside the loop.
784
+ """
785
+ time.sleep(seconds)
786
+
787
+
777
788
  def _interactive_session(
778
789
  collector: CoverageCollector,
779
790
  *,
@@ -794,7 +805,7 @@ def _interactive_session(
794
805
  try:
795
806
  while True:
796
807
  if stop is None:
797
- time.sleep(interval)
808
+ _sleep(interval)
798
809
  elif stop.wait(interval):
799
810
  console.print("[dim]window closed — finishing.[/dim]")
800
811
  break
@@ -925,7 +936,7 @@ def _run_wrapped_child(
925
936
  interrupted = False
926
937
  try:
927
938
  while child.poll() is None:
928
- time.sleep(interval)
939
+ _sleep(interval)
929
940
  _interval_flush(
930
941
  collector,
931
942
  console=console,
@@ -8,13 +8,14 @@ loop with a mocked client.
8
8
 
9
9
  Every bare session here runs against ``FakeWindow`` rather than the real
10
10
  sidecar — the window is Node and Chromium, and neither belongs in a unit
11
- test. The fake keeps ``time.sleep`` as the loop's clock, which is how the
11
+ test. The fake keeps the loop's own ``_sleep`` as its clock, which is how the
12
12
  tests below script a session's end with a ``KeyboardInterrupt``.
13
13
  """
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
17
  import json
18
+ import subprocess
18
19
  import sys
19
20
  import threading
20
21
  import time
@@ -26,6 +27,7 @@ import httpx
26
27
  import pytest
27
28
  from typer.testing import CliRunner
28
29
 
30
+ from verifaied import record as record_module
29
31
  from verifaied.cli import app
30
32
  from verifaied.client import ApiError, UploadResult
31
33
  from verifaied.collect_browser import CollectBrowserError
@@ -61,13 +63,14 @@ runner = CliRunner()
61
63
 
62
64
 
63
65
  class _SleepingEvent(threading.Event):
64
- """An Event whose wait is ``time.sleep``, so the loop tests' scripted
65
- ``time.sleep`` side effects still end a session that has a window."""
66
+ """An Event whose wait is the session loop's own sleep, so the loop
67
+ tests' scripted ``_sleep`` side effects still end a session that has a
68
+ window."""
66
69
 
67
70
  def wait(self, timeout: float | None = None) -> bool:
68
71
  if self.is_set():
69
72
  return True
70
- time.sleep(timeout or 0)
73
+ record_module._sleep(timeout or 0)
71
74
  return self.is_set()
72
75
 
73
76
 
@@ -492,7 +495,7 @@ def test_flush_upload_defaults_to_the_manual_dimension(project: Path):
492
495
 
493
496
 
494
497
  def _run_loop(sleep_side_effect, flush_side_effect):
495
- """Drive run_record with time.sleep scripted to end the session.
498
+ """Drive run_record with the loop's ``_sleep`` scripted to end the session.
496
499
 
497
500
  The ledger calls are stubbed out here — they're exercised on their own
498
501
  below, and leaving them live would make every loop test depend on how
@@ -502,7 +505,7 @@ def _run_loop(sleep_side_effect, flush_side_effect):
502
505
  with (
503
506
  patch("verifaied.record.create_session", return_value=(uuid4(), None)),
504
507
  patch("verifaied.record.finalize_session"),
505
- patch("verifaied.record.time.sleep", side_effect=sleep_side_effect),
508
+ patch("verifaied.record._sleep", side_effect=sleep_side_effect),
506
509
  patch("verifaied.record.flush_upload", side_effect=flush_side_effect) as flush,
507
510
  ):
508
511
  code = run_record(
@@ -520,6 +523,27 @@ def _run_loop(sleep_side_effect, flush_side_effect):
520
523
  return code, flush, console, err_console
521
524
 
522
525
 
526
+ def test_a_sleep_elsewhere_never_spends_the_loops_script():
527
+ """``subprocess`` polls a child it waits on with ``time.sleep`` — the git
528
+ lookup before the loop does exactly that on a busy machine — so the
529
+ script ending a session is the loop's own ``_sleep`` and nothing else's.
530
+ Here every subprocess the session starts sleeps first, as a slow one
531
+ would."""
532
+ real_run = subprocess.run
533
+
534
+ def slow_run(*args, **kwargs):
535
+ time.sleep(0.01)
536
+ return real_run(*args, **kwargs)
537
+
538
+ with patch("verifaied.suite_report.subprocess.run", side_effect=slow_run):
539
+ code, flush, _, _ = _run_loop(
540
+ sleep_side_effect=[None, KeyboardInterrupt()],
541
+ flush_side_effect=None,
542
+ )
543
+ assert code == 0
544
+ assert flush.call_count == 2
545
+
546
+
523
547
  def test_loop_uploads_on_change_and_flushes_on_ctrl_c():
524
548
  # Two ticks then Ctrl-C; the interrupt triggers one final flush.
525
549
  code, flush, console, _ = _run_loop(
@@ -607,7 +631,7 @@ def test_ctrl_c_still_uploads_after_a_failed_interval_upload(project: Path):
607
631
  patch("verifaied.record.create_session", return_value=(uuid4(), None)),
608
632
  patch("verifaied.record.finalize_session"),
609
633
  patch("verifaied.record.make_server", side_effect=capture_server),
610
- patch("verifaied.record.time.sleep", side_effect=sleep_script),
634
+ patch("verifaied.record._sleep", side_effect=sleep_script),
611
635
  patch("verifaied.record.upload", side_effect=flaky),
612
636
  ):
613
637
  code = run_record(
@@ -774,7 +798,7 @@ def test_wrapper_interrupt_stops_the_child_and_still_flushes():
774
798
  child = [sys.executable, "-c", "import time; time.sleep(30)"]
775
799
  with (
776
800
  patch("verifaied.record.flush_upload", side_effect=flush),
777
- patch("verifaied.record.time.sleep", side_effect=KeyboardInterrupt()),
801
+ patch("verifaied.record._sleep", side_effect=KeyboardInterrupt()),
778
802
  ):
779
803
  code = run_record(
780
804
  api_url="http://api.test",
@@ -1001,7 +1025,7 @@ def test_record_serves_a_real_round_trip_through_run_record():
1001
1025
 
1002
1026
  with (
1003
1027
  patch("verifaied.record.make_server", side_effect=capture_server),
1004
- patch("verifaied.record.time.sleep", side_effect=sleep_then_post),
1028
+ patch("verifaied.record._sleep", side_effect=sleep_then_post),
1005
1029
  patch("verifaied.record.flush_upload", side_effect=fake_flush),
1006
1030
  ):
1007
1031
  code = run_record(
@@ -1267,7 +1291,7 @@ def _requested_port(*, command: list[str] | None) -> tuple[int, int]:
1267
1291
  with (
1268
1292
  patch("verifaied.record.make_server", side_effect=capture_server),
1269
1293
  patch(
1270
- "verifaied.record.time.sleep",
1294
+ "verifaied.record._sleep",
1271
1295
  side_effect=None if command else [KeyboardInterrupt()],
1272
1296
  ),
1273
1297
  patch("verifaied.record.flush_upload", side_effect=lambda *a, **k: None),
@@ -1339,7 +1363,7 @@ def _record_with_ledger(
1339
1363
  ),
1340
1364
  patch("verifaied.record.flush_upload", flush),
1341
1365
  patch(
1342
- "verifaied.record.time.sleep",
1366
+ "verifaied.record._sleep",
1343
1367
  side_effect=None if command else KeyboardInterrupt(),
1344
1368
  ),
1345
1369
  ):
@@ -2220,7 +2244,7 @@ def test_a_bare_session_never_tracks_a_suite():
2220
2244
  patch("verifaied.record.create_session", MagicMock(return_value=(None, None))),
2221
2245
  patch("verifaied.record.finalize_session", MagicMock()),
2222
2246
  patch("verifaied.record.flush_upload", MagicMock(return_value=None)),
2223
- patch("verifaied.record.time.sleep", side_effect=KeyboardInterrupt()),
2247
+ patch("verifaied.record._sleep", side_effect=KeyboardInterrupt()),
2224
2248
  ):
2225
2249
  run_record(
2226
2250
  api_url="http://api.test",
@@ -2267,7 +2291,7 @@ def test_run_record_starts_the_proxy_and_closes_it(tmp_path: Path):
2267
2291
  with (
2268
2292
  patch("verifaied.record.create_session", return_value=(uuid4(), None)),
2269
2293
  patch("verifaied.record.finalize_session"),
2270
- patch("verifaied.record.time.sleep", side_effect=KeyboardInterrupt()),
2294
+ patch("verifaied.record._sleep", side_effect=KeyboardInterrupt()),
2271
2295
  patch("verifaied.record.flush_upload", return_value=None),
2272
2296
  patch("verifaied.record.start_proxy", return_value=handle) as start,
2273
2297
  ):
@@ -2332,7 +2356,7 @@ def test_no_proxy_means_start_proxy_is_never_called(tmp_path: Path):
2332
2356
  with (
2333
2357
  patch("verifaied.record.create_session", return_value=(uuid4(), None)),
2334
2358
  patch("verifaied.record.finalize_session"),
2335
- patch("verifaied.record.time.sleep", side_effect=KeyboardInterrupt()),
2359
+ patch("verifaied.record._sleep", side_effect=KeyboardInterrupt()),
2336
2360
  patch("verifaied.record.flush_upload", return_value=None),
2337
2361
  patch("verifaied.record.start_proxy") as start,
2338
2362
  ):
@@ -2490,7 +2514,7 @@ def test_run_record_stops_on_a_plan_limit_without_recording(tmp_path: Path):
2490
2514
  side_effect=ApiError(403, "Your plan covers 3 branches per repository."),
2491
2515
  ),
2492
2516
  patch("verifaied.record.flush_upload") as flush,
2493
- patch("verifaied.record.time.sleep") as sleep,
2517
+ patch("verifaied.record._sleep") as sleep,
2494
2518
  ):
2495
2519
  code = run_record(
2496
2520
  api_url="http://api.test",
@@ -2579,7 +2603,7 @@ def _bare_session(fake_window, *, browser: bool = True, url=None, proxy=False, *
2579
2603
  patch("verifaied.record.create_session", opened),
2580
2604
  patch("verifaied.record.finalize_session"),
2581
2605
  patch(
2582
- "verifaied.record.time.sleep",
2606
+ "verifaied.record._sleep",
2583
2607
  side_effect=extra.pop("sleep_side_effect", [KeyboardInterrupt()]),
2584
2608
  ),
2585
2609
  patch("verifaied.record.flush_upload", side_effect=lambda *a, **k: None),
@@ -1242,7 +1242,7 @@ wheels = [
1242
1242
 
1243
1243
  [[package]]
1244
1244
  name = "verifaied"
1245
- version = "0.34.0"
1245
+ version = "0.34.1"
1246
1246
  source = { editable = "." }
1247
1247
  dependencies = [
1248
1248
  { name = "httpx" },