test(v0): prove dynamic reusable row updates
Use one TodoRow projection for initial render and generated dynamic Vec<IntoEffect> row replacement batches, keeping the normal path on generated helpers instead of raw effects or registry plumbing. req: canonical_authoring/003
This commit is contained in:
+48
-3
@@ -427,14 +427,28 @@ fn todos_view(todos: &[TodoRecord]) -> Todos {
|
|||||||
// req: html_safety/002 req: view/001 req: canonical_authoring/003
|
// req: html_safety/002 req: view/001 req: canonical_authoring/003
|
||||||
Todos {
|
Todos {
|
||||||
summary: todo_summary(todos),
|
summary: todo_summary(todos),
|
||||||
rows: todos
|
rows: todo_rows(todos),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
fn refresh_todo_rows_effect(todos: &[TodoRecord]) -> impl IntoEffect {
|
||||||
|
// req: canonical_authoring/003
|
||||||
|
let row_updates = todo_rows(todos)
|
||||||
|
.into_iter()
|
||||||
|
.map(|row| todos::todo_row.replace(row))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
(row_updates, todos::summary.set(todo_summary(todos)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn todo_rows(todos: &[TodoRecord]) -> Vec<TodoRow> {
|
||||||
|
todos
|
||||||
.iter()
|
.iter()
|
||||||
.map(|todo| TodoRow {
|
.map(|todo| TodoRow {
|
||||||
id: TodoId(todo.id),
|
id: TodoId(todo.id),
|
||||||
title: todo.title.clone(),
|
title: todo.title.clone(),
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn todo_summary(todos: &[TodoRecord]) -> String {
|
fn todo_summary(todos: &[TodoRecord]) -> String {
|
||||||
@@ -587,6 +601,37 @@ mod tests {
|
|||||||
.is_none());
|
.is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// req: canonical_authoring/003 req: test/005
|
||||||
|
#[test]
|
||||||
|
fn reusable_todo_partial_supports_dynamic_replace_batches() {
|
||||||
|
let todos = vec![
|
||||||
|
TodoRecord {
|
||||||
|
id: 7,
|
||||||
|
title: "Ship v0".to_owned(),
|
||||||
|
},
|
||||||
|
TodoRecord {
|
||||||
|
id: 8,
|
||||||
|
title: "Write docs".to_owned(),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
let initial = ui::page(&todos_view(&todos));
|
||||||
|
let document = Html::parse_fragment(initial.as_str());
|
||||||
|
assert_eq!(
|
||||||
|
document
|
||||||
|
.select(&selector(&keyed_items_selector("li")))
|
||||||
|
.count(),
|
||||||
|
2
|
||||||
|
);
|
||||||
|
|
||||||
|
let refresh =
|
||||||
|
inspect_batch(refresh_todo_rows_effect(&todos).into_batch(ui::BUILD_FINGERPRINT));
|
||||||
|
assert_eq!(refresh.op_count(), 3);
|
||||||
|
assert!(refresh.replaces_keyed_html_containing(todos::todo_row, "7", "Ship v0"));
|
||||||
|
assert!(refresh.replaces_keyed_html_containing(todos::todo_row, "8", "Write docs"));
|
||||||
|
assert!(refresh.updates_text(todos::summary));
|
||||||
|
}
|
||||||
|
|
||||||
// req: html_safety/002 req: view/001 req: test/005
|
// req: html_safety/002 req: view/001 req: test/005
|
||||||
#[test]
|
#[test]
|
||||||
fn empty_todos_payload_is_rendered_by_a_hemplate_view() {
|
fn empty_todos_payload_is_rendered_by_a_hemplate_view() {
|
||||||
|
|||||||
Reference in New Issue
Block a user