mirror of
https://github.com/openai/codex.git
synced 2026-10-25 18:28:38 +00:00
fix(tui): guard tick_batch zero drain and remove needless async tests
- tick_batch(0) now returns empty instead of silently draining one line - has_live_tail avoids Vec allocation via field comparison - Convert 15 sync-only controller tests from tokio::test to #[test]
This commit is contained in:
committed by
Felipe Coury
parent
2fd2259286
commit
4c9b69b75d
@@ -4831,6 +4831,7 @@ mod tests {
|
||||
message: "tiny width coverage for wrapped user history".to_string(),
|
||||
text_elements: Vec::new(),
|
||||
local_image_paths: Vec::new(),
|
||||
remote_image_urls: Vec::new(),
|
||||
};
|
||||
let agent_message_cell = AgentMessageCell::new(vec!["tiny width agent line".into()], true);
|
||||
let reasoning_cell = ReasoningSummaryCell::new(
|
||||
@@ -4967,6 +4968,7 @@ mod tests {
|
||||
message: "hello".to_string(),
|
||||
text_elements: Vec::new(),
|
||||
local_image_paths: Vec::new(),
|
||||
remote_image_urls: Vec::new(),
|
||||
}) as Arc<dyn HistoryCell>;
|
||||
let head = Arc::new(AgentMessageCell::new(vec![Line::from("line 1")], true))
|
||||
as Arc<dyn HistoryCell>;
|
||||
|
||||
@@ -1485,9 +1485,7 @@ where
|
||||
tag_start += 1;
|
||||
}
|
||||
|
||||
if bytes
|
||||
.get(tag_start)
|
||||
.is_some_and(u8::is_ascii_alphabetic)
|
||||
if bytes.get(tag_start).is_some_and(u8::is_ascii_alphabetic)
|
||||
&& bytes
|
||||
.get(tag_start + 1..)
|
||||
.is_some_and(|suffix| suffix.contains(&b'>'))
|
||||
|
||||
@@ -177,7 +177,13 @@ impl StreamCore {
|
||||
|
||||
/// Batch drain: dequeue up to `max_lines`, update the emitted count.
|
||||
fn tick_batch(&mut self, max_lines: usize) -> Vec<Line<'static>> {
|
||||
let step = self.state.drain_n(max_lines.max(1));
|
||||
if max_lines == 0 {
|
||||
return Vec::new();
|
||||
}
|
||||
let step = self.state.drain_n(max_lines);
|
||||
if step.is_empty() {
|
||||
return step;
|
||||
}
|
||||
let emitted_start = self.emitted_stable_len;
|
||||
self.emitted_stable_len += step.len();
|
||||
self.advance_emitted_source_boundary(emitted_start, self.emitted_stable_len);
|
||||
@@ -205,6 +211,10 @@ impl StreamCore {
|
||||
self.rendered_lines[start..].to_vec()
|
||||
}
|
||||
|
||||
fn has_tail(&self) -> bool {
|
||||
self.enqueued_stable_len < self.rendered_lines.len()
|
||||
}
|
||||
|
||||
/// Update rendering width and rebuild queued stable lines for the new layout.
|
||||
///
|
||||
/// Re-renders once at the new width and remaps already-emitted progress by
|
||||
@@ -550,7 +560,7 @@ impl StreamController {
|
||||
}
|
||||
|
||||
pub(crate) fn has_live_tail(&self) -> bool {
|
||||
!self.current_tail_lines().is_empty()
|
||||
self.core.has_tail()
|
||||
}
|
||||
|
||||
pub(crate) fn set_width(&mut self, width: Option<usize>) {
|
||||
@@ -1161,6 +1171,35 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn controller_tick_batch_zero_is_noop() {
|
||||
let mut ctrl = stream_controller(Some(80));
|
||||
assert!(ctrl.push("line one\n"));
|
||||
assert_eq!(ctrl.queued_lines(), 1);
|
||||
|
||||
let (cell, idle) = ctrl.on_commit_tick_batch(0);
|
||||
assert!(cell.is_none(), "batch size 0 should not emit lines");
|
||||
assert!(!idle, "batch size 0 should not drain queued lines");
|
||||
assert_eq!(
|
||||
ctrl.queued_lines(),
|
||||
1,
|
||||
"queue depth should remain unchanged"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn controller_has_live_tail_reflects_tail_presence() {
|
||||
let mut ctrl = stream_controller(Some(80));
|
||||
assert!(!ctrl.has_live_tail());
|
||||
|
||||
ctrl.core.rendered_lines = vec![Line::from("tail line")];
|
||||
ctrl.core.enqueued_stable_len = 0;
|
||||
assert!(ctrl.has_live_tail());
|
||||
|
||||
ctrl.core.enqueued_stable_len = 1;
|
||||
assert!(!ctrl.has_live_tail());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn controller_set_width_partial_drain_no_lost_lines() {
|
||||
let mut ctrl = stream_controller(Some(40));
|
||||
@@ -1257,8 +1296,8 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn controller_loose_vs_tight_with_commit_ticks_matches_full() {
|
||||
#[test]
|
||||
fn controller_loose_vs_tight_with_commit_ticks_matches_full() {
|
||||
let mut ctrl = stream_controller(/*width*/ None);
|
||||
let mut lines = Vec::new();
|
||||
|
||||
@@ -1375,8 +1414,8 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn controller_streamed_table_matches_full_render_widths() {
|
||||
#[test]
|
||||
fn controller_streamed_table_matches_full_render_widths() {
|
||||
let deltas = vec![
|
||||
"| Key | Description |\n",
|
||||
"| --- | --- |\n",
|
||||
@@ -1394,8 +1433,8 @@ mod tests {
|
||||
assert_eq!(streamed, expected);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn controller_holds_blockquoted_table_tail_until_stable() {
|
||||
#[test]
|
||||
fn controller_holds_blockquoted_table_tail_until_stable() {
|
||||
let deltas = vec![
|
||||
"> | A | B |\n",
|
||||
"> | --- | --- |\n",
|
||||
@@ -1477,8 +1516,8 @@ mod tests {
|
||||
assert_eq!(streamed, expected);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn controller_does_not_hold_back_pipe_prose_without_table_delimiter() {
|
||||
#[test]
|
||||
fn controller_does_not_hold_back_pipe_prose_without_table_delimiter() {
|
||||
let mut ctrl = stream_controller(Some(80));
|
||||
|
||||
ctrl.push("status | owner | note\n");
|
||||
@@ -1515,8 +1554,8 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn controller_handles_table_immediately_after_heading() {
|
||||
#[test]
|
||||
fn controller_handles_table_immediately_after_heading() {
|
||||
let deltas = vec![
|
||||
"### 1) Basic table\n",
|
||||
"| Name | Role | Status |\n",
|
||||
@@ -1536,8 +1575,8 @@ mod tests {
|
||||
assert_eq!(streamed, expected);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn controller_renders_unicode_for_multi_table_response_shape() {
|
||||
#[test]
|
||||
fn controller_renders_unicode_for_multi_table_response_shape() {
|
||||
let source = "Absolutely. Here are several different Markdown table patterns you can use for rendering tests.\n\n| Name | Role |
|
||||
Location |\n|-------|-----------|----------|\n| Ava | Engineer | NYC |\n| Malik | Designer | Berlin |\n| Priya | PM | Remote
|
||||
|\n\n| Item | Qty | Price | In Stock |\n|:------------|----:|------:|:--------:|\n| Keyboard | 2 | 49.99 | Yes |\n| Mouse | 10
|
||||
@@ -1558,8 +1597,8 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn controller_renders_unicode_for_no_outer_pipes_table_shape() {
|
||||
#[test]
|
||||
fn controller_renders_unicode_for_no_outer_pipes_table_shape() {
|
||||
let source = "### 1) Basic\n\n| Name | Role | Active |\n|---|---|---|\n| Alice | Engineer | Yes |\n| Bob | Designer | No |\n\n### 2) No outer
|
||||
pipes\n\nCol A | Col B | Col C\n--- | --- | ---\nx | y | z\n10 | 20 | 30\n\n### 3) Another table\n\n| Key | Value |\n|---|---|\n| a | b |\n";
|
||||
|
||||
@@ -1584,8 +1623,8 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn controller_stabilizes_first_no_outer_pipes_table_in_response() {
|
||||
#[test]
|
||||
fn controller_stabilizes_first_no_outer_pipes_table_in_response() {
|
||||
let deltas = vec![
|
||||
"### No outer pipes first\n\n",
|
||||
"Col A | Col B | Col C\n",
|
||||
@@ -1615,8 +1654,8 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn controller_stabilizes_two_column_no_outer_table_in_response() {
|
||||
#[test]
|
||||
fn controller_stabilizes_two_column_no_outer_table_in_response() {
|
||||
let deltas = vec![
|
||||
"A | B\n",
|
||||
"--- | ---\n",
|
||||
@@ -1642,8 +1681,8 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn controller_converts_no_outer_table_between_preboxed_sections() {
|
||||
#[test]
|
||||
fn controller_converts_no_outer_table_between_preboxed_sections() {
|
||||
let source = " ┌───────┬──────────┬────────┐\n │ Name │ Role │ Active │\n ├───────┼──────────┼────────┤\n │ Alice │ Engineer │ Yes │\n │ Bob │ Designer │ No │\n │ Cara │ PM │ Yes │\n └───────┴──────────┴────────┘\n\n ### 3) No outer pipes\n\n Col A | Col B | Col C\n --- | --- | ---\n x | y | z\n 10 | 20 | 30\n\n ┌─────────────────┬────────┬────────────────────────┐\n │ Example │ Output │ Notes │\n ├─────────────────┼────────┼────────────────────────┤\n │ a | b │ `a │ b` │\n │ npm run test │ ok │ Inline code formatting │\n │ SELECT * FROM t │ 3 rows │ SQL snippet │\n └─────────────────┴────────┴────────────────────────┘\n";
|
||||
|
||||
let deltas = source
|
||||
@@ -1670,8 +1709,8 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn controller_keeps_markdown_fenced_tables_mutable_until_finalize() {
|
||||
#[test]
|
||||
fn controller_keeps_markdown_fenced_tables_mutable_until_finalize() {
|
||||
let source = "```md\n| A | B |\n|---|---|\n| 1 | 2 |\n```\n";
|
||||
let deltas = vec![
|
||||
"```md\n",
|
||||
@@ -1697,8 +1736,8 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn controller_keeps_markdown_fenced_no_outer_tables_mutable_until_finalize() {
|
||||
#[test]
|
||||
fn controller_keeps_markdown_fenced_no_outer_tables_mutable_until_finalize() {
|
||||
let source =
|
||||
"```md\nCol A | Col B | Col C\n--- | --- | ---\nx | y | z\n10 | 20 | 30\n```\n";
|
||||
let deltas = vec![
|
||||
@@ -1728,8 +1767,8 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn controller_keeps_non_markdown_fenced_tables_as_code() {
|
||||
#[test]
|
||||
fn controller_keeps_non_markdown_fenced_tables_as_code() {
|
||||
let source = "```sh\n| A | B |\n|---|---|\n| 1 | 2 |\n```\n";
|
||||
let deltas = vec![
|
||||
"```sh\n",
|
||||
@@ -1755,8 +1794,8 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn plan_controller_streamed_table_matches_finalize_render() {
|
||||
#[test]
|
||||
fn plan_controller_streamed_table_matches_finalize_render() {
|
||||
let deltas = vec![
|
||||
"## Build plan\n\n",
|
||||
"| Step | Owner |\n",
|
||||
@@ -1783,8 +1822,8 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn plan_controller_streamed_markdown_fenced_table_matches_finalize_render() {
|
||||
#[test]
|
||||
fn plan_controller_streamed_markdown_fenced_table_matches_finalize_render() {
|
||||
let deltas = vec![
|
||||
"## Build plan\n\n",
|
||||
"```md\n",
|
||||
|
||||
Reference in New Issue
Block a user