documents: a picture shrinks within a narrow table cell; tree tests in their own file; test comments within ten words
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
4801555e0d
commit
2e196a10a7
4 files changed
+215
-206
No files matched your search
@@ -300,6 +300,7 @@ impl Draw<'_> {
|
||||
let cell = |blocks: &[Node], column: usize, header: bool, cx: &App| {
|
||||
div()
|
||||
.flex_1()
|
||||
.min_w_0()
|
||||
.flex()
|
||||
.px_3()
|
||||
.py_1p5()
|
||||
@@ -315,6 +316,7 @@ impl Draw<'_> {
|
||||
})
|
||||
.child(
|
||||
div()
|
||||
.max_w_full()
|
||||
.flex()
|
||||
.flex_col()
|
||||
.gap_1()
|
||||
|
||||
+17
-6
@@ -23,7 +23,7 @@ fn hit(page: usize) -> PageHit {
|
||||
}
|
||||
}
|
||||
|
||||
/// Three tall pages and the hits found; a press while pinning records the note asked.
|
||||
/// Three tall pages and hits; a pinning press records notes.
|
||||
struct Reader {
|
||||
query: Entity<TextInput>,
|
||||
width: f32,
|
||||
@@ -60,7 +60,7 @@ fn open(cx: &mut TestAppContext) -> (Entity<Reader>, Noted, &mut VisualTestConte
|
||||
open_with(400.0, None, cx)
|
||||
}
|
||||
|
||||
/// Pages `width` points wide, with a hit on the second, current from the first frame when `current` says.
|
||||
/// Pages `width` wide, a hit on page two, maybe current.
|
||||
fn open_with(
|
||||
width: f32,
|
||||
current: Option<usize>,
|
||||
@@ -86,7 +86,7 @@ fn settle(cx: &mut VisualTestContext) {
|
||||
cx.run_until_parked();
|
||||
}
|
||||
|
||||
/// A point on the pages, below the header and the find bar, at the view's middle.
|
||||
/// A point on the pages, below the bars, mid-view.
|
||||
fn on_pages(cx: &mut VisualTestContext) -> Point<Pixels> {
|
||||
cx.update(|window, _| point(window.viewport_size().width / 2.0, px(300.0)))
|
||||
}
|
||||
@@ -102,7 +102,7 @@ fn wheel(down: f32, cx: &mut VisualTestContext) {
|
||||
settle(cx);
|
||||
}
|
||||
|
||||
/// Turns pinning on with the header's last button, then presses the pages at their middle; returns the note asked.
|
||||
/// Turns pinning on, presses mid-page; the note asked.
|
||||
fn pin(cx: &mut VisualTestContext, noted: &Noted) -> (usize, Point<f32>) {
|
||||
let at = on_pages(cx);
|
||||
pin_at(at, cx, noted)
|
||||
@@ -143,7 +143,7 @@ fn a_note_lands_where_the_press_is_on_a_scrolled_page(cx: &mut TestAppContext) {
|
||||
assert_eq!(scrolled.y, top.y + 150.0, "the press counts the scroll");
|
||||
}
|
||||
|
||||
/// Scrolls `down`, makes the hit current, then pins a note at the same window point.
|
||||
/// Scrolls `down`, makes the hit current, pins a note.
|
||||
fn revealed(down: f32, cx: &mut TestAppContext) -> (usize, Point<f32>) {
|
||||
let (reader, noted, cx) = open(cx);
|
||||
if down > 0.0 {
|
||||
@@ -201,7 +201,7 @@ fn a_hit_current_from_the_first_frame_comes_into_view(cx: &mut TestAppContext) {
|
||||
assert_eq!(at_once, later);
|
||||
}
|
||||
|
||||
/// A field outside a zen view, and how often Escape left zen.
|
||||
/// A field outside zen, and the Escapes that left zen.
|
||||
struct Zen {
|
||||
outside: Entity<TextInput>,
|
||||
on: bool,
|
||||
@@ -375,6 +375,17 @@ fn a_picture_in_a_table_cell_draws(cx: &mut TestAppContext) {
|
||||
assert_eq!(drawn_picture(table, 400.0, cx), size(px(200.0), px(100.0)));
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn a_picture_in_a_narrow_cell_shrinks_within_it(cx: &mut TestAppContext) {
|
||||
let table = "| A | B |
|
||||
| - | - |
|
||||
|  | b |
|
||||
";
|
||||
let drawn = drawn_picture(table, 160.0, cx);
|
||||
assert!(drawn.width < px(80.0), "within its half: {drawn:?}");
|
||||
assert_eq!(drawn.height, drawn.width / 2.0, "at its ratio");
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn a_formula_that_fails_shows_why_and_its_source(cx: &mut TestAppContext) {
|
||||
cx.update(Theme::init);
|
||||
|
||||
@@ -310,203 +310,4 @@ fn styled(inline: &mut Inline, text: &str, style: Style) {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn blocks_nest_as_written() {
|
||||
let nodes = parse(
|
||||
"# Lift\n\nBlend **toward** [white](https://ely.dev).\n\n- [x] clamp\n- [ ] gamma\n\n> quoted\n\n```rust\nfn main() {}\n```\n\n---\n",
|
||||
);
|
||||
assert!(matches!(&nodes[0], Node::Heading(1, text) if text.text == "Lift"));
|
||||
let Node::Paragraph(line) = &nodes[1] else {
|
||||
panic!("a paragraph, not {:?}", nodes[1])
|
||||
};
|
||||
assert_eq!(line.text, "Blend toward white.");
|
||||
assert_eq!(line.styles, [(6..12, Style::Strong), (13..18, Style::Link)]);
|
||||
assert_eq!(line.links, [(13..18, "https://ely.dev".to_string())]);
|
||||
let Node::List { start: None, items } = &nodes[2] else {
|
||||
panic!("a list, not {:?}", nodes[2])
|
||||
};
|
||||
assert_eq!(
|
||||
items.iter().map(|(task, _)| *task).collect::<Vec<_>>(),
|
||||
[Some(true), Some(false)]
|
||||
);
|
||||
assert!(matches!(&items[0].1[0], Node::Paragraph(text) if text.text == "clamp"));
|
||||
assert!(matches!(&nodes[3], Node::Quote(inner) if inner.len() == 1));
|
||||
assert_eq!(
|
||||
nodes[4],
|
||||
Node::Code {
|
||||
language: Some("rust".into()),
|
||||
text: "fn main() {}".into()
|
||||
}
|
||||
);
|
||||
assert_eq!(nodes[5], Node::Rule);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_image_inside_an_image_is_the_outer_one() {
|
||||
// markdown-rs drops the inner image from the alt.
|
||||
assert_eq!(
|
||||
parse("](outer.png)"),
|
||||
[Node::Image {
|
||||
alt: "outer ".into(),
|
||||
url: "outer.png".into(),
|
||||
link: None
|
||||
}]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_image_splits_its_paragraph_and_references_resolve() {
|
||||
let nodes =
|
||||
parse("Before ![a][pic] after [site].\n\n[pic]: a.png\n[site]: https://ely.dev\n");
|
||||
assert!(matches!(&nodes[0], Node::Paragraph(text) if text.text == "Before "));
|
||||
assert_eq!(
|
||||
nodes[1],
|
||||
Node::Image {
|
||||
alt: "a".into(),
|
||||
url: "a.png".into(),
|
||||
link: None
|
||||
}
|
||||
);
|
||||
let Node::Paragraph(after) = &nodes[2] else {
|
||||
panic!("a paragraph, not {:?}", nodes[2])
|
||||
};
|
||||
assert_eq!(after.text, " after site.");
|
||||
assert_eq!(after.links, [(7..11, "https://ely.dev".to_string())]);
|
||||
assert_eq!(nodes.len(), 3, "definitions draw nothing: {nodes:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_soft_break_reads_as_a_space_and_a_hard_one_as_a_line() {
|
||||
for (source, shown) in [
|
||||
("one\ntwo \nthree", "one two\nthree"),
|
||||
("one\r\ntwo \r\nthree", "one two\nthree"),
|
||||
("one\rtwo \rthree", "one two\nthree"),
|
||||
] {
|
||||
let nodes = parse(source);
|
||||
assert!(
|
||||
matches!(&nodes[0], Node::Paragraph(text) if text.text == shown),
|
||||
"{source:?} reads {nodes:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn definitions_nested_in_quotes_and_lists_resolve() {
|
||||
for source in [
|
||||
"[site] ![pic]\n\n> [site]: https://ely.dev\n> [pic]: a.png\n",
|
||||
"[site] ![pic]\n\n- [site]: https://ely.dev\n- [pic]: a.png\n",
|
||||
] {
|
||||
let nodes = parse(source);
|
||||
let Node::Paragraph(text) = &nodes[0] else {
|
||||
panic!("a paragraph, not {:?}", nodes[0])
|
||||
};
|
||||
assert_eq!(text.links, [(0..4, "https://ely.dev".to_string())]);
|
||||
assert_eq!(
|
||||
nodes[1],
|
||||
Node::Image {
|
||||
alt: "pic".into(),
|
||||
url: "a.png".into(),
|
||||
link: None
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_image_inside_styles_and_links_stays_an_image() {
|
||||
let nodes = parse("*a  b* [](https://ely.dev)");
|
||||
let Node::Paragraph(before) = &nodes[0] else {
|
||||
panic!("a paragraph, not {:?}", nodes[0])
|
||||
};
|
||||
assert_eq!(
|
||||
(before.text.as_str(), &before.styles[..]),
|
||||
("a ", &[(0..2, Style::Emphasis)][..])
|
||||
);
|
||||
assert_eq!(
|
||||
nodes[1],
|
||||
Node::Image {
|
||||
alt: "x".into(),
|
||||
url: "x.png".into(),
|
||||
link: None
|
||||
}
|
||||
);
|
||||
let Node::Paragraph(after) = &nodes[2] else {
|
||||
panic!("a paragraph, not {:?}", nodes[2])
|
||||
};
|
||||
assert_eq!(
|
||||
(after.text.as_str(), &after.styles[..]),
|
||||
(" b ", &[(0..2, Style::Emphasis)][..])
|
||||
);
|
||||
assert_eq!(
|
||||
nodes[3],
|
||||
Node::Image {
|
||||
alt: "y".into(),
|
||||
url: "y.png".into(),
|
||||
link: Some("https://ely.dev".into())
|
||||
}
|
||||
);
|
||||
assert_eq!(nodes.len(), 4, "{nodes:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_heading_keeps_its_images_after_it() {
|
||||
let nodes = parse("# Lift ");
|
||||
assert!(matches!(&nodes[0], Node::Heading(1, text) if text.text == "Lift "));
|
||||
assert!(matches!(&nodes[1], Node::Image { url, .. } if url == "x.png"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_math_stands_alone() {
|
||||
assert_eq!(parse("$$c = 1$$"), [Node::Math("c = 1".into())]);
|
||||
assert_eq!(parse("$$\nc = 1\n$$"), [Node::Math("c = 1".into())]);
|
||||
let Node::Paragraph(inline) = &parse("so $c$ holds")[0] else {
|
||||
panic!("inline math stays in its paragraph")
|
||||
};
|
||||
assert_eq!(inline.styles, [(3..4, Style::Math)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tables_keep_their_cells_and_alignment() {
|
||||
let nodes = parse("| Name | Lift |\n|:--|--:|\n| accent | 0.5 |\n");
|
||||
let Node::Table { aligns, head, rows } = &nodes[0] else {
|
||||
panic!("a table, not {:?}", nodes[0])
|
||||
};
|
||||
assert_eq!(aligns, &[AlignKind::Left, AlignKind::Right]);
|
||||
let text = |cell: &[Node]| match cell {
|
||||
[Node::Paragraph(line)] => line.text.clone(),
|
||||
other => panic!("one line, not {other:?}"),
|
||||
};
|
||||
assert_eq!(
|
||||
head.iter().map(|cell| text(cell)).collect::<Vec<_>>(),
|
||||
["Name", "Lift"]
|
||||
);
|
||||
assert_eq!(text(&rows[0][1]), "0.5");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_picture_in_a_cell_stays_a_picture() {
|
||||
let nodes = parse("| Picture |\n| --- |\n|  |\n");
|
||||
let Node::Table { rows, .. } = &nodes[0] else {
|
||||
panic!("a table, not {:?}", nodes[0])
|
||||
};
|
||||
assert!(
|
||||
matches!(&rows[0][0][..], [Node::Image { alt, url, .. }] if alt == "shot" && url == "assets/shot.png")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn footnotes_number_their_references_and_hold_their_body() {
|
||||
let nodes = parse("Lift[^a].\n\n[^a]: Toward white.\n");
|
||||
let Node::Paragraph(line) = &nodes[0] else {
|
||||
panic!("a paragraph, not {:?}", nodes[0])
|
||||
};
|
||||
assert_eq!(line.text, "Lift[a].");
|
||||
assert_eq!(line.styles, [(4..7, Style::Footnote)]);
|
||||
assert!(
|
||||
matches!(&nodes[1], Node::Footnote { label, body } if label == "a" && body.len() == 1)
|
||||
);
|
||||
}
|
||||
}
|
||||
mod tests;
|
||||
@@ -0,0 +1,195 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn blocks_nest_as_written() {
|
||||
let nodes = parse(
|
||||
"# Lift\n\nBlend **toward** [white](https://ely.dev).\n\n- [x] clamp\n- [ ] gamma\n\n> quoted\n\n```rust\nfn main() {}\n```\n\n---\n",
|
||||
);
|
||||
assert!(matches!(&nodes[0], Node::Heading(1, text) if text.text == "Lift"));
|
||||
let Node::Paragraph(line) = &nodes[1] else {
|
||||
panic!("a paragraph, not {:?}", nodes[1])
|
||||
};
|
||||
assert_eq!(line.text, "Blend toward white.");
|
||||
assert_eq!(line.styles, [(6..12, Style::Strong), (13..18, Style::Link)]);
|
||||
assert_eq!(line.links, [(13..18, "https://ely.dev".to_string())]);
|
||||
let Node::List { start: None, items } = &nodes[2] else {
|
||||
panic!("a list, not {:?}", nodes[2])
|
||||
};
|
||||
assert_eq!(
|
||||
items.iter().map(|(task, _)| *task).collect::<Vec<_>>(),
|
||||
[Some(true), Some(false)]
|
||||
);
|
||||
assert!(matches!(&items[0].1[0], Node::Paragraph(text) if text.text == "clamp"));
|
||||
assert!(matches!(&nodes[3], Node::Quote(inner) if inner.len() == 1));
|
||||
assert_eq!(
|
||||
nodes[4],
|
||||
Node::Code {
|
||||
language: Some("rust".into()),
|
||||
text: "fn main() {}".into()
|
||||
}
|
||||
);
|
||||
assert_eq!(nodes[5], Node::Rule);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_image_inside_an_image_is_the_outer_one() {
|
||||
// markdown-rs drops the inner image from the alt.
|
||||
assert_eq!(
|
||||
parse("](outer.png)"),
|
||||
[Node::Image {
|
||||
alt: "outer ".into(),
|
||||
url: "outer.png".into(),
|
||||
link: None
|
||||
}]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_image_splits_its_paragraph_and_references_resolve() {
|
||||
let nodes = parse("Before ![a][pic] after [site].\n\n[pic]: a.png\n[site]: https://ely.dev\n");
|
||||
assert!(matches!(&nodes[0], Node::Paragraph(text) if text.text == "Before "));
|
||||
assert_eq!(
|
||||
nodes[1],
|
||||
Node::Image {
|
||||
alt: "a".into(),
|
||||
url: "a.png".into(),
|
||||
link: None
|
||||
}
|
||||
);
|
||||
let Node::Paragraph(after) = &nodes[2] else {
|
||||
panic!("a paragraph, not {:?}", nodes[2])
|
||||
};
|
||||
assert_eq!(after.text, " after site.");
|
||||
assert_eq!(after.links, [(7..11, "https://ely.dev".to_string())]);
|
||||
assert_eq!(nodes.len(), 3, "definitions draw nothing: {nodes:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_soft_break_reads_as_a_space_and_a_hard_one_as_a_line() {
|
||||
for (source, shown) in [
|
||||
("one\ntwo \nthree", "one two\nthree"),
|
||||
("one\r\ntwo \r\nthree", "one two\nthree"),
|
||||
("one\rtwo \rthree", "one two\nthree"),
|
||||
] {
|
||||
let nodes = parse(source);
|
||||
assert!(
|
||||
matches!(&nodes[0], Node::Paragraph(text) if text.text == shown),
|
||||
"{source:?} reads {nodes:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn definitions_nested_in_quotes_and_lists_resolve() {
|
||||
for source in [
|
||||
"[site] ![pic]\n\n> [site]: https://ely.dev\n> [pic]: a.png\n",
|
||||
"[site] ![pic]\n\n- [site]: https://ely.dev\n- [pic]: a.png\n",
|
||||
] {
|
||||
let nodes = parse(source);
|
||||
let Node::Paragraph(text) = &nodes[0] else {
|
||||
panic!("a paragraph, not {:?}", nodes[0])
|
||||
};
|
||||
assert_eq!(text.links, [(0..4, "https://ely.dev".to_string())]);
|
||||
assert_eq!(
|
||||
nodes[1],
|
||||
Node::Image {
|
||||
alt: "pic".into(),
|
||||
url: "a.png".into(),
|
||||
link: None
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_image_inside_styles_and_links_stays_an_image() {
|
||||
let nodes = parse("*a  b* [](https://ely.dev)");
|
||||
let Node::Paragraph(before) = &nodes[0] else {
|
||||
panic!("a paragraph, not {:?}", nodes[0])
|
||||
};
|
||||
assert_eq!(
|
||||
(before.text.as_str(), &before.styles[..]),
|
||||
("a ", &[(0..2, Style::Emphasis)][..])
|
||||
);
|
||||
assert_eq!(
|
||||
nodes[1],
|
||||
Node::Image {
|
||||
alt: "x".into(),
|
||||
url: "x.png".into(),
|
||||
link: None
|
||||
}
|
||||
);
|
||||
let Node::Paragraph(after) = &nodes[2] else {
|
||||
panic!("a paragraph, not {:?}", nodes[2])
|
||||
};
|
||||
assert_eq!(
|
||||
(after.text.as_str(), &after.styles[..]),
|
||||
(" b ", &[(0..2, Style::Emphasis)][..])
|
||||
);
|
||||
assert_eq!(
|
||||
nodes[3],
|
||||
Node::Image {
|
||||
alt: "y".into(),
|
||||
url: "y.png".into(),
|
||||
link: Some("https://ely.dev".into())
|
||||
}
|
||||
);
|
||||
assert_eq!(nodes.len(), 4, "{nodes:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_heading_keeps_its_images_after_it() {
|
||||
let nodes = parse("# Lift ");
|
||||
assert!(matches!(&nodes[0], Node::Heading(1, text) if text.text == "Lift "));
|
||||
assert!(matches!(&nodes[1], Node::Image { url, .. } if url == "x.png"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_math_stands_alone() {
|
||||
assert_eq!(parse("$$c = 1$$"), [Node::Math("c = 1".into())]);
|
||||
assert_eq!(parse("$$\nc = 1\n$$"), [Node::Math("c = 1".into())]);
|
||||
let Node::Paragraph(inline) = &parse("so $c$ holds")[0] else {
|
||||
panic!("inline math stays in its paragraph")
|
||||
};
|
||||
assert_eq!(inline.styles, [(3..4, Style::Math)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tables_keep_their_cells_and_alignment() {
|
||||
let nodes = parse("| Name | Lift |\n|:--|--:|\n| accent | 0.5 |\n");
|
||||
let Node::Table { aligns, head, rows } = &nodes[0] else {
|
||||
panic!("a table, not {:?}", nodes[0])
|
||||
};
|
||||
assert_eq!(aligns, &[AlignKind::Left, AlignKind::Right]);
|
||||
let text = |cell: &[Node]| match cell {
|
||||
[Node::Paragraph(line)] => line.text.clone(),
|
||||
other => panic!("one line, not {other:?}"),
|
||||
};
|
||||
assert_eq!(
|
||||
head.iter().map(|cell| text(cell)).collect::<Vec<_>>(),
|
||||
["Name", "Lift"]
|
||||
);
|
||||
assert_eq!(text(&rows[0][1]), "0.5");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_picture_in_a_cell_stays_a_picture() {
|
||||
let nodes = parse("| Picture |\n| --- |\n|  |\n");
|
||||
let Node::Table { rows, .. } = &nodes[0] else {
|
||||
panic!("a table, not {:?}", nodes[0])
|
||||
};
|
||||
assert!(
|
||||
matches!(&rows[0][0][..], [Node::Image { alt, url, .. }] if alt == "shot" && url == "assets/shot.png")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn footnotes_number_their_references_and_hold_their_body() {
|
||||
let nodes = parse("Lift[^a].\n\n[^a]: Toward white.\n");
|
||||
let Node::Paragraph(line) = &nodes[0] else {
|
||||
panic!("a paragraph, not {:?}", nodes[0])
|
||||
};
|
||||
assert_eq!(line.text, "Lift[a].");
|
||||
assert_eq!(line.styles, [(4..7, Style::Footnote)]);
|
||||
assert!(matches!(&nodes[1], Node::Footnote { label, body } if label == "a" && body.len() == 1));
|
||||
}
|
||||
Reference in new issue
Block a user