mirror of
https://github.com/codewhale-hq/Codewhale.git
synced 2026-11-11 10:01:30 -10:00
test(tui): cover Markdown drag-copy with regression tests (#6156)
Three focused tests in mouse_ui/primary_tests.rs: default-on Markdown payload preserving fences with a cell-count toast, rendered-text fallback when selection_copy_markdown=false, and multi-cell blank-line join with count. Update mouse_selection_autocopies_on_release_without_ctrl_c for the toast receipt (clipboard assertion unchanged). Validation: tui::mouse_ui::primary_tests 8 passed, 0 failed; updated ui test 1 passed; updated ui test FAILS without the fix (status-sink assertion), proving it pins the new behavior.
This commit is contained in:
1 parent
3b29358469
commit
0dc66e6166
2 files changed
+125
-1
No files matched your search
@@ -209,3 +209,115 @@ fn transcript_drag_released_over_composer_keeps_caret_and_clears_drag() {
|
||||
assert_eq!(app.clipboard.read_primary_text(), Some(expected));
|
||||
assert_eq!(app.clipboard.last_written_text(), Some("REGULAR_CLIPBOARD"));
|
||||
}
|
||||
|
||||
fn select_all_transcript_lines(app: &mut App) {
|
||||
let last = app
|
||||
.viewport
|
||||
.transcript_cache
|
||||
.lines()
|
||||
.len()
|
||||
.saturating_sub(1);
|
||||
app.viewport.transcript_selection.anchor = Some(TranscriptSelectionPoint {
|
||||
line_index: 0,
|
||||
column: 0,
|
||||
});
|
||||
app.viewport.transcript_selection.head = Some(TranscriptSelectionPoint {
|
||||
line_index: last,
|
||||
column: 80,
|
||||
});
|
||||
}
|
||||
|
||||
fn ensure_transcript(app: &mut App) {
|
||||
app.resync_history_revisions();
|
||||
app.viewport.transcript_cache.ensure(
|
||||
&app.history,
|
||||
&app.history_revisions,
|
||||
80,
|
||||
app.transcript_render_options(),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transcript_copy_defaults_to_markdown_source_and_names_cell_count() {
|
||||
let (mut app, _) = composer();
|
||||
assert!(
|
||||
app.viewport.selection_copy_markdown,
|
||||
"markdown copy defaults on"
|
||||
);
|
||||
let content = "# Title\n\n```rust\nlet x = 1;\n```".to_string();
|
||||
app.history = vec![HistoryCell::Assistant {
|
||||
content: content.clone(),
|
||||
streaming: false,
|
||||
}];
|
||||
ensure_transcript(&mut app);
|
||||
select_all_transcript_lines(&mut app);
|
||||
let toasts_before = app.status_toasts.len();
|
||||
copy_active_selection(&mut app);
|
||||
assert_eq!(app.clipboard.last_written_text(), Some(content.as_str()));
|
||||
assert_eq!(app.status_toasts.len(), toasts_before + 1);
|
||||
let toast = app.status_toasts.back().expect("markdown copy toast");
|
||||
assert!(
|
||||
toast.text.contains("(1)"),
|
||||
"toast names the projected cell count, got {:?}",
|
||||
toast.text
|
||||
);
|
||||
assert!(
|
||||
app.status_message.is_none(),
|
||||
"toast path must not touch the legacy status sink"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transcript_copy_falls_back_to_rendered_text_when_markdown_is_off() {
|
||||
let (mut app, _) = composer();
|
||||
app.viewport.selection_copy_markdown = false;
|
||||
app.history = vec![HistoryCell::Assistant {
|
||||
content: "# Title\n\n```rust\nlet x = 1;\n```".to_string(),
|
||||
streaming: false,
|
||||
}];
|
||||
ensure_transcript(&mut app);
|
||||
select_all_transcript_lines(&mut app);
|
||||
let expected = selection_to_text(&app).expect("rendered fallback text");
|
||||
let toasts_before = app.status_toasts.len();
|
||||
copy_active_selection(&mut app);
|
||||
assert_eq!(
|
||||
app.clipboard.last_written_text(),
|
||||
Some(expected.as_str())
|
||||
);
|
||||
assert_eq!(app.status_message.as_deref(), Some("Selection copied"));
|
||||
assert_eq!(app.status_toasts.len(), toasts_before);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transcript_copy_joins_cells_with_blank_lines_and_counts_them() {
|
||||
let (mut app, _) = composer();
|
||||
app.history = vec![
|
||||
HistoryCell::User {
|
||||
content: "first question".into(),
|
||||
},
|
||||
HistoryCell::Assistant {
|
||||
content: "second answer".into(),
|
||||
streaming: false,
|
||||
},
|
||||
];
|
||||
ensure_transcript(&mut app);
|
||||
select_all_transcript_lines(&mut app);
|
||||
// A partial drag still rounds out to whole cells.
|
||||
app.viewport.transcript_selection.anchor = Some(TranscriptSelectionPoint {
|
||||
line_index: 0,
|
||||
column: 2,
|
||||
});
|
||||
let toasts_before = app.status_toasts.len();
|
||||
copy_active_selection(&mut app);
|
||||
assert_eq!(
|
||||
app.clipboard.last_written_text(),
|
||||
Some("first question\n\nsecond answer")
|
||||
);
|
||||
assert_eq!(app.status_toasts.len(), toasts_before + 1);
|
||||
let toast = app.status_toasts.back().expect("multi-cell copy toast");
|
||||
assert!(
|
||||
toast.text.contains("(2)"),
|
||||
"toast names the projected cell count, got {:?}",
|
||||
toast.text
|
||||
);
|
||||
}
|
||||
@@ -3655,7 +3655,19 @@ fn mouse_selection_autocopies_on_release_without_ctrl_c() {
|
||||
},
|
||||
);
|
||||
|
||||
assert_eq!(app.status_message.as_deref(), Some("Selection copied"));
|
||||
// Drag-release autocopy now takes the Markdown-source path (#6156): the
|
||||
// clipboard holds canonical cell content and the receipt is a toast
|
||||
// naming the projected cell count, not the legacy status sink.
|
||||
assert!(
|
||||
app.status_message.is_none(),
|
||||
"markdown copy must not touch the legacy status sink"
|
||||
);
|
||||
let toast = app.status_toasts.back().expect("markdown copy toast");
|
||||
assert!(
|
||||
toast.text.contains("(1)"),
|
||||
"toast names the projected cell count, got {:?}",
|
||||
toast.text
|
||||
);
|
||||
assert!(
|
||||
app.clipboard
|
||||
.last_written_text()
|
||||
|
||||
Reference in new issue
Block a user