Viney Claude Opus 5 (1M context) commited on
Commit
d2a33ff
Β·
1 Parent(s): 24d7b8c

test: cover render_summary and The Brief's zone dispatcher

Browse files

render_summary is the branch's flagship renderer -- drift_summary's
renderer, the sole caller of render_tone_strip, and the only place the
spec's two anti-duplication rules become observable -- and had no
executable test at all.

Two tests in the established spy mould: six eligible deltas in must
produce exactly three cards plus the pointer at the full view, and a
tone-only brief must produce the trajectory sparkline alongside the
rl_summary_none empty state (Ruling A-8's path, previously pinned only
at the order level).

Also pins render()'s dispatcher: inverting `if key in zone_3: continue`
would ship commodity blocks above the fold and differentiated ones
inside a collapsed expander -- the precise inversion this sub-project
exists to fix -- with a green suite. All three tests were confirmed to
fail against a deliberately mutated implementation.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Files changed (1) hide show
  1. tests/test_brief_order.py +126 -0
tests/test_brief_order.py CHANGED
@@ -317,3 +317,129 @@ def test_ask_cta_closes_the_sourced_facts_zone():
317
  from dashboard.verdict import ZONE_2
318
 
319
  assert ZONE_2[-1] == "ask_cta"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
317
  from dashboard.verdict import ZONE_2
318
 
319
  assert ZONE_2[-1] == "ask_cta"
320
+
321
+
322
+ # ── render_summary: the flagship renderer ───────────────────────────────────
323
+ #
324
+ # The Brief's promoted drift panel. It is the renderer for drift_summary, the
325
+ # SOLE caller of render_tone_strip, and the only place the spec's two
326
+ # anti-duplication rules ("at most three cards", "always point at the full
327
+ # view") become observable.
328
+
329
+ _TONE_METRIC = (
330
+ "hedge-word rate 27β†’13β†’15β†’55 per 10k words over FY2025β†’Q32026 "
331
+ "(rising 3 quarters) β†’ more cautious"
332
+ )
333
+
334
+
335
+ def _tone_delta(term: str = "hedging language") -> dict:
336
+ delta = _delta("tone_trend", term, "HIGH")
337
+ delta["computed_metric"] = _TONE_METRIC
338
+ delta["source"] = "transcript"
339
+ return delta
340
+
341
+
342
+ def test_render_summary_shows_at_most_three_cards_and_points_at_the_full_view(
343
+ monkeypatch,
344
+ ):
345
+ """Both anti-duplication rules at the render level: The Brief promotes
346
+ only the top three wording changes, and always tells the reader where the
347
+ other three live. Nothing else covers either rule at any level."""
348
+ import dashboard.redline_view as mod
349
+ from dashboard.i18n import t
350
+
351
+ captured: list[str] = []
352
+ monkeypatch.setattr(
353
+ mod.st, "markdown", lambda html, **kw: captured.append(str(html))
354
+ )
355
+
356
+ brief = {"quarter_deltas": [
357
+ _delta("risk_added", f"drift {i}") for i in range(6)
358
+ ]}
359
+ mod.render_summary(brief, limit=3)
360
+
361
+ joined = "".join(captured)
362
+
363
+ assert joined.count('class="primer-card"') == 3
364
+ assert "drift 0" in joined and "drift 1" in joined and "drift 2" in joined
365
+ assert "drift 3" not in joined
366
+ assert "drift 4" not in joined
367
+ assert "drift 5" not in joined
368
+ assert t("rl_summary_more").format(section=t("nav_signals")) in joined
369
+
370
+
371
+ def test_render_summary_shows_the_tone_strip_and_the_empty_state_for_a_tone_only_brief(
372
+ monkeypatch,
373
+ ):
374
+ """Ruling A-8's path at the render level, not just the order level:
375
+ tone_trend is excluded from top_deltas, so a tone-only brief must still
376
+ produce the trajectory sparkline AND say plainly that no wording changed
377
+ -- rather than an empty panel or a silent no-op."""
378
+ import dashboard.redline_view as mod
379
+ import dashboard.tone_strip as tone_mod
380
+ from dashboard.i18n import t
381
+
382
+ captured: list[str] = []
383
+ monkeypatch.setattr(
384
+ mod.st, "markdown", lambda html, **kw: captured.append(str(html))
385
+ )
386
+ monkeypatch.setattr(
387
+ tone_mod.st, "markdown", lambda html, **kw: captured.append(str(html))
388
+ )
389
+
390
+ mod.render_summary({"quarter_deltas": [_tone_delta()]}, limit=3)
391
+
392
+ joined = "".join(captured)
393
+
394
+ assert "<svg" in joined
395
+ assert "hedging language" in joined
396
+ assert t("rl_summary_none") in joined
397
+ assert 'class="primer-card"' not in joined
398
+
399
+
400
+ # ── render(): the zone dispatcher ───────────────────────────────────────────
401
+
402
+ def test_render_keeps_zone_3_inside_the_expander_and_everything_else_above_it(
403
+ monkeypatch,
404
+ ):
405
+ """The one behaviour of render()'s dispatcher. Inverting
406
+ `if key in zone_3: continue` would ship the commodity reference blocks
407
+ above the fold and the differentiated ones inside a collapsed expander --
408
+ the precise inversion this sub-project exists to fix -- with a green
409
+ suite."""
410
+ from contextlib import contextmanager
411
+
412
+ import dashboard.verdict as mod
413
+
414
+ seen: list[str] = []
415
+
416
+ @contextmanager
417
+ def _expander(*args, **kwargs):
418
+ seen.append("<expander>")
419
+ yield None
420
+
421
+ monkeypatch.setattr(mod.st, "markdown", lambda *a, **kw: None)
422
+ monkeypatch.setattr(mod.st, "expander", _expander)
423
+ monkeypatch.setattr(
424
+ mod, "_block_renderers",
425
+ lambda brief, ticker: {
426
+ key: (lambda k=key: seen.append(k))
427
+ for key in (*mod.ZONE_1, *mod.ZONE_2, *mod.ZONE_3)
428
+ },
429
+ )
430
+
431
+ brief = _full_brief()
432
+ mod.render(brief)
433
+
434
+ order = mod.brief_block_order(brief)
435
+ boundary = seen.index("<expander>")
436
+ above = seen[:boundary]
437
+ inside = seen[boundary + 1:]
438
+
439
+ assert inside, "the expander rendered nothing"
440
+ assert set(inside) == set(mod.ZONE_3)
441
+ assert set(above) == set(order) - set(mod.ZONE_3)
442
+ assert not set(above) & set(mod.ZONE_3)
443
+ # Order is preserved within each side, not merely partitioned.
444
+ assert above == [k for k in order if k not in set(mod.ZONE_3)]
445
+ assert inside == [k for k in order if k in set(mod.ZONE_3)]