Files
codex/codex-rs/tui/src/render/renderable_tests.rs
Felipe Coury c884536d84 feat(tui): reland token activity command (#27925)
## Why

[#25345](https://github.com/openai/codex/pull/25345) was approved,
green, and squash-merged into its stacked base branch,
`fcoury/tokenmaxxing-api`. Four minutes later, that base branch was
force-pushed back to an API-only rebased head while preparing
[#25344](https://github.com/openai/codex/pull/25344) for `main`. As a
result, the squash commit from #25345 was orphaned and the TUI command
never reached `main` or a release.

This PR relands the orphaned TUI change from
[`411410b8`](411410b85c)
on current `main`.

## What changed

- Add `/usage`, `/usage daily`, `/usage weekly`, and `/usage cumulative`
for account token activity.
- Fetch account usage asynchronously through the existing
`account/usage/read` app-server RPC.
- Render daily, weekly, and cumulative activity with theme-aware
terminal palettes and bounded transient cards.
- Preserve transcript ordering while assistant streams, history
consolidations, active cells, and hooks complete.
- Hide `/usage` from completion when backend auth is unavailable while
keeping typed-command guidance.
- Carry current-main behavior forward for cwd-aware Markdown parsing,
Windows Terminal color detection, and personal access token auth.
- Clear pending usage cards on thread rollback and delay completed cards
until live hook output is committed.
- Add focused regression and snapshot coverage for loading, auth errors,
invalid views, rollback, hook ordering, layout, and charts.

## Prior review

The original implementation was approved by Eric Traut in #25345 after
testing multiple themes and light/dark terminals. This PR preserves that
reviewed implementation while adapting it to current `main` and adding
regression coverage for newer rollback and hook lifecycle behavior.

## Validation

- `just test -p codex-tui token_activity palette renderable
usage_command` — 37 passed.
- Focused rollback, hook-ordering, and error snapshot tests — 4 passed.
- `just fix -p codex-tui` — passed.
- `UV_CACHE_DIR=/private/tmp/codex-uv-cache just fmt` — passed.
- `cargo insta pending-snapshots` — no pending snapshots.
- `just test -p codex-tui` — 2,870 passed; two unrelated guardian
feature-flag tests failed because their expected `OverrideTurnContext`
event was absent:
-
`update_feature_flags_disabling_guardian_clears_manual_review_policy_without_history`
-
`update_feature_flags_disabling_guardian_clears_review_policy_and_restores_default`
- `just argument-comment-lint` could not complete because the local
Bazel LLVM `compiler-rt` repository is missing `include/sanitizer/*.h`.
The touched Rust diff was manually inspected and no missing
opaque-literal argument comments were found.
2026-06-12 17:33:43 -07:00

73 lines
1.7 KiB
Rust

use super::*;
use pretty_assertions::assert_eq;
struct HeightRenderable(u16);
impl HeightRenderable {
fn with_height(height: u16) -> Self {
Self(height)
}
}
impl Renderable for HeightRenderable {
fn render(&self, _area: Rect, _buf: &mut Buffer) {}
fn desired_height(&self, _width: u16) -> u16 {
self.0
}
}
#[test]
fn flex_redistributes_space_unused_by_short_children() {
let mut flex = FlexRenderable::new();
flex.push(
/*flex*/ 1,
RenderableItem::Owned(Box::new(HeightRenderable::with_height(/*height*/ 20))),
);
flex.push(
/*flex*/ 1,
RenderableItem::Owned(Box::new(HeightRenderable::with_height(/*height*/ 2))),
);
let allocated = flex.allocate(Rect::new(
/*x*/ 0, /*y*/ 0, /*width*/ 80, /*height*/ 10,
));
assert_eq!(
allocated
.into_iter()
.map(|area| area.height)
.collect::<Vec<_>>(),
vec![8, 2],
);
}
#[test]
fn flex_reserves_non_flex_space_before_flexible_children() {
let mut flex = FlexRenderable::new();
flex.push(
/*flex*/ 1,
RenderableItem::Owned(Box::new(HeightRenderable::with_height(/*height*/ 20))),
);
flex.push(
/*flex*/ 0,
RenderableItem::Owned(Box::new(HeightRenderable::with_height(/*height*/ 2))),
);
flex.push(
/*flex*/ 1,
RenderableItem::Owned(Box::new(HeightRenderable::with_height(/*height*/ 20))),
);
let allocated = flex.allocate(Rect::new(
/*x*/ 0, /*y*/ 0, /*width*/ 80, /*height*/ 10,
));
assert_eq!(
allocated
.into_iter()
.map(|area| area.height)
.collect::<Vec<_>>(),
vec![4, 2, 4],
);
}