mitsuhiko / insta

A snapshot testing library for rust
https://insta.rs
Apache License 2.0
2.23k stars 100 forks source link

Configure for the inline snapshot indentation #605

Closed andylokandy closed 1 month ago

andylokandy commented 1 month ago

Hi , thank you for the awesome tool! Currently,cargo insta review generates inline snapshots in the form like:

assert_snapshot!(
    test.execute("select id, value from t1"),
    @r###"
+----+-------+
| id | value |
+----+-------+
| 2  | 102   |
+----+-------+
| 3  | 103   |
+----+-------+
| 4  | 104   |
+----+-------+

(3 rows)
"###
);

I wonder if it's possbile to make the following output with project-level configuration:

assert_snapshot!(
    test.execute("select id, value from t1"),
    @r###"
    +----+-------+
    | id | value |
    +----+-------+
    | 2  | 102   |
    +----+-------+
    | 3  | 103   |
    +----+-------+
    | 4  | 104   |
    +----+-------+

    (3 rows)
    "###
);

Maybe related to https://github.com/mitsuhiko/insta/issues/457

max-sixty commented 1 month ago

Thanks for the issue!

It should give reasonable indentation already. Could you post a reproducible example? The source can just be a literal string.

andylokandy commented 1 month ago

Starting from this test:

#[test]
fn test_foo() {
    assert_snapshot!(
        "aaa\nbbb\nccc\nddd",
        @""
    );
}

After review:

#[test]
fn test_foo() {
    assert_snapshot!(
        "aaa\nbbb\nccc\nddd",
        @r###"
    aaa
    bbb
    ccc
    ddd
    "###
    );
}

If starting from oneline:

#[test]
fn test_foo() {
    assert_snapshot!("aaa\nbbb\nccc\nddd", @"");
}

After review:

#[test]
fn test_foo() {
    assert_snapshot!("aaa\nbbb\nccc\nddd", @r###"
    aaa
    bbb
    ccc
    ddd
    "###);
}

I've a tool using ast-grep to replace @ to - to make cargo fmt works (https://github.com/mitsuhiko/insta/issues/499):

#[test]
fn test_foo() {
    assert_snapshot!("aaa\nbbb\nccc\nddd", -r###"
    aaa
    bbb
    ccc
    ddd
    "###);
}

cargo fmt:

#[test]
fn test_foo() {
    assert_snapshot!(
        "aaa\nbbb\nccc\nddd",
        -r###"
    aaa
    bbb
    ccc
    ddd
    "###
    );
}

replace - back to @:

#[test]
fn test_foo() {
    assert_snapshot!(
        "aaa\nbbb\nccc\nddd",
        @r###"
    aaa
    bbb
    ccc
    ddd
    "###
    );
}
max-sixty commented 1 month ago

Sorry for being slow — am I understanding correctly that the current output and the desired output have the same indentation? And the difference is the opening delimiter?

(Am on phone so possibly I'm missing something...)

andylokandy commented 1 month ago

Thank you for quick reply! The desired output is

#[test]
fn test_foo() {
    assert_snapshot!(
        "aaa\nbbb\nccc\nddd",
        @r###"
        aaa
        bbb
        ccc
        ddd
        "###
    );
}

while I get

#[test]
fn test_foo() {
    assert_snapshot!(
        "aaa\nbbb\nccc\nddd",
        @r###"
    aaa
    bbb
    ccc
    ddd
    "###
    );
}
max-sixty commented 1 month ago

I think a couple of things here:

andylokandy commented 1 month ago

Indeed. These maybe project-specific preference. The better way could be keeping the default behavior and format using ast-grep in project desiring different style.

Thank you very much!

andylokandy commented 1 month ago

so we need something that isn't a valid rust expression. So I can't think of a way around it

rustfmt is requiring a syntactical valid expression, but not semantically valid expression. Thus there is room to find such patterns. For example, my using -r###""### utilize the fact that unary minus to a string is valid in syntax but invalid in type. Symbols like *, !, ?(postfix) are also possible.

Maybe further, in assert_snapshot!(expr, string_lit), we can always treat it as inline snap if the second argument is string literal because it's not likely assert_snapshot!(name, expr) has a simple string literal as expr (comparing a string lit with string lit).

max-sixty commented 1 month ago

(great, will reply in #499)

max-sixty commented 1 month ago

To reply to:

Maybe further, in assert_snapshot!(expr, string_lit), we can always treat it as inline snap if the second argument is string literal because it's not likely assert_snapshot!(name, expr) has a simple string literal as expr (comparing a string lit with string lit).

I would vote to stay away from any ambiguities like this; confusion there would be very expensive...