test(tui): de-flake parse-invocation counter via thread-local

`parse_invocations_increment` and `render_parsed_does_not_call_parse` both
read the global PARSE_INVOCATIONS atomic. They were racing whenever any
other test in the suite called `parse()` in parallel — the global counter
would tick once for each unrelated call and the assertion (== 2 / == 0)
would mismatch.

Switching to `thread_local!<Cell<u64>>` gives each test thread its own
counter, so concurrent callers from other tests can't pollute the result.
Tested across 8 sequential full-suite runs: 8/8 green (was ~40% green).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Hunter Bown
2026-04-26 00:00:32 -05:00
parent 9467d26db7
commit 75de26c7a1
+13 -5
View File
@@ -27,7 +27,8 @@
use std::sync::Arc;
#[cfg(any(test, feature = "perf-counters"))]
use std::sync::atomic::{AtomicU64, Ordering};
#[cfg(any(test, feature = "perf-counters"))]
use std::cell::Cell;
use ratatui::style::{Modifier, Style};
use ratatui::text::{Line, Span};
@@ -40,18 +41,23 @@ use crate::palette;
///
/// Available in test builds and behind the `perf-counters` feature flag so
/// release builds pay no cost.
// Thread-local instead of a global atomic so concurrent tests that call
// `parse()` don't pollute each other's counters. Each test thread sees only
// its own invocations.
#[cfg(any(test, feature = "perf-counters"))]
static PARSE_INVOCATIONS: AtomicU64 = AtomicU64::new(0);
thread_local! {
static PARSE_INVOCATIONS: Cell<u64> = const { Cell::new(0) };
}
#[cfg(any(test, feature = "perf-counters"))]
#[must_use]
pub fn parse_invocation_count() -> u64 {
PARSE_INVOCATIONS.load(Ordering::Relaxed)
PARSE_INVOCATIONS.with(|c| c.get())
}
#[cfg(any(test, feature = "perf-counters"))]
pub fn reset_parse_invocation_count() {
PARSE_INVOCATIONS.store(0, Ordering::Relaxed);
PARSE_INVOCATIONS.with(|c| c.set(0));
}
/// One classified line of markdown source, width-independent.
@@ -109,7 +115,7 @@ impl ParsedMarkdown {
#[must_use]
pub fn parse(content: &str) -> ParsedMarkdown {
#[cfg(any(test, feature = "perf-counters"))]
PARSE_INVOCATIONS.fetch_add(1, Ordering::Relaxed);
PARSE_INVOCATIONS.with(|c| c.set(c.get() + 1));
let mut blocks = Vec::new();
let mut in_code_block = false;
@@ -485,6 +491,8 @@ mod tests {
#[test]
fn parse_invocations_increment() {
// Counter is thread-local, so concurrent tests calling `parse()`
// can't pollute each other.
reset_parse_invocation_count();
let _ = parse("hello\n");
let _ = parse("world\n");