Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit da8c9c52 authored by Martin Geisler's avatar Martin Geisler Committed by Gerrit Code Review
Browse files

Merge "pdl: enable snapshot testing via ‘cargo test’"

parents 66c2f93e 262d096a
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -47,6 +47,10 @@ rust_test_host {
    data: [
        ":rustfmt",
        ":rustfmt.toml",
        "test/generated/preamble.rs",
        "test/generated/packet_decl_empty.rs",
        "test/generated/packet_decl_simple_little_endian.rs",
        "test/generated/packet_decl_simple_big_endian.rs",
    ],
}

+11 −9
Original line number Diff line number Diff line
@@ -556,7 +556,7 @@ mod tests {
    use super::*;
    use crate::ast;
    use crate::parser::parse_inline;
    use crate::test_utils::{assert_eq_with_diff, rustfmt};
    use crate::test_utils::{assert_snapshot_eq, rustfmt};

    /// Parse a string fragment as a PDL file.
    ///
@@ -571,8 +571,7 @@ mod tests {
    #[test]
    fn test_generate_preamble() {
        let actual_code = generate_preamble(Path::new("some/path/foo.pdl")).unwrap();
        let expected_code = include_str!("../test/generated/preamble.rs");
        assert_eq_with_diff(&rustfmt(expected_code), &rustfmt(&actual_code));
        assert_snapshot_eq("test/generated/preamble.rs", &rustfmt(&actual_code));
    }

    #[test]
@@ -587,8 +586,7 @@ mod tests {
        let children = HashMap::new();
        let decl = &grammar.declarations[0];
        let actual_code = generate_decl(&grammar, &packets, &children, decl).unwrap();
        let expected_code = include_str!("../test/generated/packet_decl_empty.rs");
        assert_eq_with_diff(&rustfmt(expected_code), &rustfmt(&actual_code));
        assert_snapshot_eq("test/generated/packet_decl_empty.rs", &rustfmt(&actual_code));
    }

    #[test]
@@ -607,8 +605,10 @@ mod tests {
        let children = HashMap::new();
        let decl = &grammar.declarations[0];
        let actual_code = generate_decl(&grammar, &packets, &children, decl).unwrap();
        let expected_code = include_str!("../test/generated/packet_decl_simple_little_endian.rs");
        assert_eq_with_diff(&rustfmt(expected_code), &rustfmt(&actual_code));
        assert_snapshot_eq(
            "test/generated/packet_decl_simple_little_endian.rs",
            &rustfmt(&actual_code),
        );
    }

    #[test]
@@ -627,7 +627,9 @@ mod tests {
        let children = HashMap::new();
        let decl = &grammar.declarations[0];
        let actual_code = generate_decl(&grammar, &packets, &children, decl).unwrap();
        let expected_code = include_str!("../test/generated/packet_decl_simple_big_endian.rs");
        assert_eq_with_diff(&rustfmt(expected_code), &rustfmt(&actual_code));
        assert_snapshot_eq(
            "test/generated/packet_decl_simple_big_endian.rs",
            &rustfmt(&actual_code),
        );
    }
}
+51 −0
Original line number Diff line number Diff line
@@ -5,7 +5,9 @@
// rest of the `pdl` crate. To make this work, avoid `use crate::`
// statements below.

use std::fs;
use std::io::Write;
use std::path::Path;
use std::process::{Command, Stdio};
use tempfile::NamedTempFile;

@@ -95,3 +97,52 @@ pub fn diff(left: &str, right: &str) -> String {
pub fn assert_eq_with_diff(left: &str, right: &str) {
    assert!(left == right, "texts did not match, diff:\n{}\n", diff(left, right));
}

/// Compare a string with a snapshot file.
///
/// The `snapshot_path` is relative to the current working directory
/// of the test binary. This depends on how you execute the tests:
///
/// * When using `atest`: The current working directory is a random
///   temporary directory. You need to ensure that the snapshot file
///   is installed into this directory. You do this by adding the
///   snapshot to the `data` attribute of your test rule
///
/// * When using Cargo: The current working directory is set to
///   `CARGO_MANIFEST_DIR`, which is where the `Cargo.toml` file is
///   found.
///
/// If you run the test with Cargo and the `UPDATE_SNAPSHOTS`
/// environment variable is set, then the `actual_content` will be
/// written to `snapshot_path`. Otherwise the content is compared and
/// a panic is triggered if they differ.
#[track_caller]
pub fn assert_snapshot_eq<P: AsRef<Path>>(snapshot_path: P, actual_content: &str) {
    let snapshot = snapshot_path.as_ref();
    let snapshot_content = fs::read(&snapshot).unwrap_or_else(|err| {
        panic!("Could not read snapshot from {}: {}", snapshot.display(), err)
    });
    let snapshot_content = String::from_utf8(snapshot_content).expect("Snapshot was not UTF-8");

    // Normal comparison if UPDATE_SNAPSHOTS is unset.
    if std::env::var("UPDATE_SNAPSHOTS").is_err() {
        return assert_eq_with_diff(&snapshot_content, actual_content);
    }

    // Bail out if we are not using Cargo.
    if std::env::var("CARGO_MANIFEST_DIR").is_err() {
        panic!("Please unset UPDATE_SNAPSHOTS if you are not using Cargo");
    }

    if actual_content != snapshot_content {
        eprintln!(
            "Updating snapshot {}: {} -> {} bytes",
            snapshot.display(),
            snapshot_content.len(),
            actual_content.len()
        );
        fs::write(&snapshot_path, actual_content).unwrap_or_else(|err| {
            panic!("Could not write snapshot to {}: {}", snapshot.display(), err)
        });
    }
}
+4 −1
Original line number Diff line number Diff line
@@ -4,9 +4,12 @@ use std::process::Command;
// The integration test in this file is not part of the pdl crate, and
// so we cannot directly depend on anything from pdl. However, we can
// include the test_utils.rs file directly.
//
// The module is public to avoid an "function is never used" error,
// which is triggered because we don't use all test_utils functions.

#[path = "../src/test_utils.rs"]
mod test_utils;
pub mod test_utils;
use test_utils::{assert_eq_with_diff, find_binary, rustfmt};

fn strip_blank_lines(text: &str) -> String {