Strategies for testing View
output
#2628
Replies: 3 comments
-
I guess the question is -- What are you actually testing here? It appears that you are testing whether the I agree that testing based on the HTML output is relatively difficult, in part because hydration keys need to be unique (so generating the same thing twice will not and should not give identical results, unless you reset the hydration keys in between) It is possible to do it using something like |
Beta Was this translation helpful? Give feedback.
-
You're right, of course. This particular test is a little contrived. I had hoped to expand the Here is what I have so far: use leptos::{component, view, IntoView};
use markdown::to_html;
use std::{
fs::File,
io::Read,
path::{Path, PathBuf},
};
use thiserror::Error;
#[derive(Debug, Error)]
pub enum MdParseError {
#[error("The markdown file {0} could not be opened")]
PathNotOpened(String),
#[error("The markdown file could not be read into the `String` buffer: {0}")]
FileReadFailure(String),
}
pub trait MdParse {
fn md_parse(self) -> Result<String, MdParseError>;
}
impl MdParse for &str {
fn md_parse(self) -> Result<String, MdParseError> {
Ok(to_html(self))
}
}
impl MdParse for String {
fn md_parse(self) -> Result<String, MdParseError> {
Ok(to_html(self.as_str()))
}
}
impl MdParse for &Path {
fn md_parse(self) -> Result<String, MdParseError> {
if let Ok(mut file) = File::open(self) {
let mut buf = String::new();
let _ = file
.read_to_string(&mut buf)
.map_err(|e| MdParseError::FileReadFailure(e.to_string()));
let html = to_html(buf.as_str());
Ok(html)
} else {
Err(MdParseError::PathNotOpened(format!("{:?}", self)))
}
}
}
#[component]
pub fn Markdown<T: MdParse>(md: T) -> impl IntoView {
if let Ok(html) = md.md_parse() {
view! { <div inner_html=html></div> }
} else {
view! { <div>"This Markdown could not be parsed"</div> }
}
} |
Beta Was this translation helpful? Give feedback.
-
I think, based on your comments, that I won't bother testing the functions that just call methods from the At the moment, I am doing this: #[cfg(test)]
mod tests {
use super::*;
use leptos::{create_runtime, Oco};
use regex::Regex;
/// Strips hydration attributes, newline characters, and HTML comments from the output of
/// View::render_to_string().
fn strip_view_attributes(s: Oco<'static, str>) -> String {
// This regex is admittedly a bit hacky, but it's only for tests.
let re = Regex::new(r#"\s+data-hk="[^"]+"\s*|\n|<!--[^!]+-->"#).unwrap();
let stripped = re.replace_all(s.as_str(), "").to_string();
stripped
}
#[test]
fn markdown_from_file() {
let runtime = create_runtime();
let md = Path::new(r"tests/markdown.md");
let md_view = Markdown(MarkdownProps { md })
.into_view()
.render_to_string();
let md_view = strip_view_attributes(md_view);
assert_eq!(
md_view,
r"<div><h1>The document title</h1><p>This is plain text.</p><ul><li>item 1</li><li>item 2</li></ul><p><code>inline code</code></p></div>"
);
runtime.dispose();
}
} If I keep the document very simple and the number of tests small, it seems like a reasonable sanity check. Definitely interested in other ideas about how to test this type of component. Thanks for your time. |
Beta Was this translation helpful? Give feedback.
-
Thanks to Greg, and everyone contributing—I really love the framework.
I have been creating some components that generate
View
s from Markdown, and I am trying to find a reliable way of testing the output. There are a couple of obstacles:Testing occurs outside the runtime. I have been manually calling
create_runtime()
andruntime.dispose()
on every test, to avoid getting aRuntimeDisposed
error. Is that the best approach, or is there a way to set up a runtime and use it for all tests?When converting a
View
to a string forassert
comparisons, the tests often fail because of differences in data attributes, or differences in the wrapping comments Leptos adds around theView
. Is there a way to strip them out, or make sure they match? Is converting to string even the best way to compare generatedView
s?There is an additional issue that the
markdown
crate outputs\n
characters, and Leptos doesn't, but that is a bit more specific to my use case.Here is an example of a failing test:
The test fails with the comparison (formatted by me, to make reading easier):
So I am basically happy with the output of the component, but I can't design the right test for it. Would appreciate any input on how to go about this. At the moment, it seems like a helper function stripping all HTML comments, all newlines, and all data attributes is the only way to get a meaningful comparison.
Beta Was this translation helpful? Give feedback.
All reactions