Skip to content

Conversation

@katrinafyi
Copy link
Contributor

I think it would be useful to be able to define test fixtures within the test code. Most of the time, fixtures are really simple with only a few links. The current system needs you to make a directory and file in the fixtures folder which is a bit inconvenient. Also, when reading the test code, you'd have to separately open the fixture file to learn the content of the test.

With this change, the test files are defined in the test code so it's all visible at one location. It looks like this:

        let temp = tempdir()?;
        let dir = DirBuilder::new(temp.path());

        let file_without_ext = dir.str(
            "file-without-ext",
            r#"
# Test File
[Example](https://example.com)
[Local](local.md)
            "#,
        )?;

However, the DirBuilder code is pretty simple and doesn't need to exist. If this idea was something which we want, it could simply be done using writeln! in the test code. DirBuilder does make it slightly easier because Rust's filesystem functions are a bit disorganised and hard to find/use. I don't really mind either way.

@thomas-zahner
Copy link
Member

Most of the time, fixtures are really simple with only a few links.

True, maybe we could replace some/many fixtures with such inline definitions.

If this idea was something which we want, it could simply be done using writeln! in the test code.

I don't understand what you mean here. Isn't writeln! what's used right now? Or do you refer to other tests which haven't changed so far?

@katrinafyi
Copy link
Contributor Author

katrinafyi commented Nov 4, 2025

Oh, I'm thinking of future test cases. I mean that instead of adding this new DirBuilder, we could just use writeln! more often when writing new tests. I think DirBuilder does improve the ease of writing these test files, but only very slightly. So maybe it's not worth adding.

Another thought I've had is that test files could be defined in Rust using TOML:

make_dir!(r#"
"test_file.md" = '''
[link](https://asd.com)
'''

"test_file.html" = '''
<p> fdsjaio </p>
'''
"#)

This was my original idea when thinking about this problem, but maybe this is even more crazy :')

@katrinafyi
Copy link
Contributor Author

Thinking of abandoning this for now, unless there's desire to see it merged.

@thomas-zahner
Copy link
Member

So I think ideally we have a very simple way to define inline fixtures for single files without directory structure. As soon as there is some directory structure I personally prefer it to be in the file system as it's less code and complexity.

So yes, I'm also in favor of abandoning the idea of a DirBuilder. But I agree with the idea that for single small files which are only used in one test we should inline the content. This makes it more readable. So any directory structure is where I would draw the line and this makes a directory builder unnecessary.

I'd gladly accept a PR which introduces such a simple helper function which creates a temporary file without special configurable structure. Then this function should be used in every test where applicable.

@katrinafyi
Copy link
Contributor Author

So I think ideally we have a very simple way to define inline fixtures for single files without directory structure. As soon as there is some directory structure I personally prefer it to be in the file system as it's less code and complexity.

Hm, that's really interesting because I have almost the exact opposite view :-) I think that if the directory structure gets more complex, it means that the test is testing more complicated logic. And so, it becomes even more useful to have the directory defined in the test code so they can be seen at the same place. If that makes sense.

In any case, I'll close this for now :)

@katrinafyi katrinafyi closed this Nov 17, 2025
@mre
Copy link
Member

mre commented Nov 17, 2025

How do you feel about a combination of assert_fs and indoc?

Here’s an incomplete draft:

// In Cargo.toml
[dev-dependencies]
assert_fs = "1.1"
indoc = "2.0"

// In your test file
use assert_fs::prelude::*;
use assert_fs::TempDir;
use indoc::indoc;

fn fixture(files: &[(&str, &str)]) -> TempDir {
    let temp = TempDir::new().unwrap();
    for (path, content) in files {
        temp.child(path).write_str(content).unwrap();
    }
    temp
}

#[test]
fn test_finds_broken_links() {
    let temp = fixture(&[
        ("index.html", indoc! {r#"
            <html>
                <a href="exists.html">Good link</a>
                <a href="missing.html">Broken link</a>
            </html>
        "#}),
        ("exists.html", "<h1>This page exists</h1>"),
    ]);
    
    // ...
}

#[test]
fn test_nested_links() {
    let temp = fixture(&[
        ("index.html", r#"<a href="docs/page.html">Link</a>"#),
        ("docs/page.html", r#"<a href="../index.html">Back</a>"#),
    ]);
    
    // ...
}

https://docs.rs/assert_fs
https://docs.rs/indoc

@thomas-zahner
Copy link
Member

How do you feel about a combination of assert_fs and indoc?

That's really cool 👍

Hm, that's really interesting because I have almost the exact opposite view

Haha interesting. I just feel like a bigger nested directory structure is easier to navigate/understand by actually having it on disk rather as code and it's the simple cases we could inline in the tests first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants