blob: 379752d02ba7ae28a5df0ad6162f2354aa44fe4a [file] [log] [blame] [edit]
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Various utility functions used in tests.
// This file is included directly into integration tests in the
// `tests/` directory. These tests are compiled without access to the
// rest of the `pdl` crate. To make this work, avoid `use crate::`
// statements below.
use googletest::prelude::{assert_that, eq};
use std::fs;
use std::path::Path;
/// Format Rust code in `input`.
pub fn format_rust(input: &str) -> String {
let syntax_tree = syn::parse_file(input).expect("Could not parse {input:#?} as Rust code");
let formatted = prettyplease::unparse(&syntax_tree);
format!("#![rustfmt::skip]\n{formatted}")
}
/// 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 update_snapshots = std::env::var("UPDATE_SNAPSHOTS").is_ok();
let snapshot = snapshot_path.as_ref();
let snapshot_content = match fs::read(snapshot) {
Ok(content) => content,
Err(_) if update_snapshots => Vec::new(),
Err(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 !update_snapshots {
assert_that!(actual_content, eq(&snapshot_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)
});
}
}