turn on insta snapshot for step file output (#5732)
* turn on insta snapshot for step file output Signed-off-by: Jess Frazelle <github@jessfraz.com> * use a macro for the kcl-samples Signed-off-by: Jess Frazelle <github@jessfraz.com> * Update rust/kcl-directory-test-macro/src/lib.rs Co-authored-by: Jonathan Tran <jonnytran@gmail.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * control the order Signed-off-by: Jess Frazelle <github@jessfraz.com> * engine Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * update steps Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) --------- Signed-off-by: Jess Frazelle <github@jessfraz.com> Co-authored-by: Jonathan Tran <jonnytran@gmail.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
@ -1,18 +1,12 @@
|
||||
//! Run all the KCL samples in the `kcl_samples` directory.
|
||||
//!
|
||||
//! Use the `KCL_SAMPLES_ONLY=gear` environment variable to run only a subset of
|
||||
//! the samples, in this case, all those that start with "gear".
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fs,
|
||||
io::Write,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use anyhow::Result;
|
||||
use fnv::FnvHashSet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio::task::JoinSet;
|
||||
|
||||
use super::Test;
|
||||
|
||||
@ -25,76 +19,37 @@ lazy_static::lazy_static! {
|
||||
static ref OUTPUTS_DIR: PathBuf = Path::new("tests/kcl_samples").to_path_buf();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse() {
|
||||
#[kcl_directory_test_macro::test_all_dirs("../public/kcl-samples")]
|
||||
fn parse(dir_name: &str, dir_path: &Path) {
|
||||
let t = test(dir_name, dir_path.join("main.kcl").to_str().unwrap().to_owned());
|
||||
let write_new = matches!(
|
||||
std::env::var("INSTA_UPDATE").as_deref(),
|
||||
Ok("auto" | "always" | "new" | "unseen")
|
||||
);
|
||||
let filter = filter_from_env();
|
||||
let tests = kcl_samples_inputs(filter.as_deref());
|
||||
let expected_outputs = kcl_samples_outputs(filter.as_deref());
|
||||
|
||||
assert!(!tests.is_empty(), "No KCL samples found");
|
||||
|
||||
let input_names = FnvHashSet::from_iter(tests.iter().map(|t| t.name.clone()));
|
||||
|
||||
for test in tests {
|
||||
if write_new {
|
||||
// Ensure the directory exists for new tests.
|
||||
std::fs::create_dir_all(test.output_dir.clone()).unwrap();
|
||||
}
|
||||
super::parse_test(&test);
|
||||
if write_new {
|
||||
// Ensure the directory exists for new tests.
|
||||
std::fs::create_dir_all(t.output_dir.clone()).unwrap();
|
||||
}
|
||||
|
||||
// Ensure that inputs aren't missing.
|
||||
let missing = expected_outputs
|
||||
.into_iter()
|
||||
.filter(|name| !input_names.contains(name))
|
||||
.collect::<Vec<_>>();
|
||||
assert!(missing.is_empty(), "Expected input kcl-samples for the following. If these are no longer tests, delete the expected output directories for them in {}: {missing:?}", OUTPUTS_DIR.to_string_lossy());
|
||||
super::parse_test(&t);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unparse() {
|
||||
#[kcl_directory_test_macro::test_all_dirs("../public/kcl-samples")]
|
||||
fn unparse(dir_name: &str, dir_path: &Path) {
|
||||
// kcl-samples don't always use correct formatting. We don't ignore the
|
||||
// test because we want to allow the just command to work. It's actually
|
||||
// fine when no test runs.
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn kcl_test_execute() {
|
||||
let filter = filter_from_env();
|
||||
let tests = kcl_samples_inputs(filter.as_deref());
|
||||
let expected_outputs = kcl_samples_outputs(filter.as_deref());
|
||||
#[kcl_directory_test_macro::test_all_dirs("../public/kcl-samples")]
|
||||
async fn kcl_test_execute(dir_name: &str, dir_path: &Path) {
|
||||
let t = test(dir_name, dir_path.join("main.kcl").to_str().unwrap().to_owned());
|
||||
super::execute_test(&t, true, true).await;
|
||||
}
|
||||
|
||||
assert!(!tests.is_empty(), "No KCL samples found");
|
||||
|
||||
// Note: This is unordered.
|
||||
let mut tasks = JoinSet::new();
|
||||
// Mapping from task ID to test index.
|
||||
let mut id_to_index = HashMap::new();
|
||||
// Spawn a task for each test.
|
||||
for (index, test) in tests.iter().cloned().enumerate() {
|
||||
let handle = tasks.spawn(async move {
|
||||
super::execute_test(&test, true, true).await;
|
||||
});
|
||||
id_to_index.insert(handle.id(), index);
|
||||
}
|
||||
|
||||
// Join all the tasks and collect the failures. We cannot just join_all
|
||||
// because insta's error messages don't clearly indicate which test failed.
|
||||
let mut failed = vec![None; tests.len()];
|
||||
while let Some(result) = tasks.join_next().await {
|
||||
let Err(err) = result else {
|
||||
continue;
|
||||
};
|
||||
// When there's an error, store the test name and error message.
|
||||
let index = *id_to_index.get(&err.id()).unwrap();
|
||||
failed[index] = Some(format!("{}: {err}", &tests[index].name));
|
||||
}
|
||||
let failed = failed.into_iter().flatten().collect::<Vec<_>>();
|
||||
assert!(failed.is_empty(), "Failed tests: {}", failed.join("\n"));
|
||||
#[test]
|
||||
fn test_after_engine_ensure_kcl_samples_manifest_etc() {
|
||||
let tests = kcl_samples_inputs();
|
||||
let expected_outputs = kcl_samples_outputs();
|
||||
|
||||
// Ensure that inputs aren't missing.
|
||||
let input_names = FnvHashSet::from_iter(tests.iter().map(|t| t.name.clone()));
|
||||
@ -125,7 +80,7 @@ async fn kcl_test_execute() {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let step_file = OUTPUTS_DIR.join(&tests.name).join("exported_step.snap.step");
|
||||
let step_file = OUTPUTS_DIR.join(&tests.name).join(super::EXPORTED_STEP_NAME);
|
||||
if !step_file.exists() {
|
||||
panic!("Missing step for test: {}", tests.name);
|
||||
}
|
||||
@ -147,7 +102,7 @@ async fn kcl_test_execute() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generate_manifest() {
|
||||
fn test_after_engine_generate_manifest() {
|
||||
// Generate the manifest.json
|
||||
generate_kcl_manifest(&INPUTS_DIR).unwrap();
|
||||
}
|
||||
@ -161,11 +116,7 @@ fn test(test_name: &str, entry_point: String) -> Test {
|
||||
}
|
||||
}
|
||||
|
||||
fn filter_from_env() -> Option<String> {
|
||||
std::env::var("KCL_SAMPLES_ONLY").ok().filter(|s| !s.is_empty())
|
||||
}
|
||||
|
||||
fn kcl_samples_inputs(filter: Option<&str>) -> Vec<Test> {
|
||||
fn kcl_samples_inputs() -> Vec<Test> {
|
||||
let mut tests = Vec::new();
|
||||
|
||||
// Collect all directory entries first and sort them by name for consistent ordering
|
||||
@ -197,11 +148,6 @@ fn kcl_samples_inputs(filter: Option<&str>) -> Vec<Test> {
|
||||
// Skip output directories.
|
||||
continue;
|
||||
}
|
||||
if let Some(filter) = &filter {
|
||||
if !dir_name_str.starts_with(filter) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
eprintln!("Found KCL sample: {:?}", dir_name.to_string_lossy());
|
||||
// Look for the entry point inside the directory.
|
||||
let sub_dir = INPUTS_DIR.join(dir_name);
|
||||
@ -216,7 +162,7 @@ fn kcl_samples_inputs(filter: Option<&str>) -> Vec<Test> {
|
||||
tests
|
||||
}
|
||||
|
||||
fn kcl_samples_outputs(filter: Option<&str>) -> Vec<String> {
|
||||
fn kcl_samples_outputs() -> Vec<String> {
|
||||
let mut outputs = Vec::new();
|
||||
|
||||
for entry in OUTPUTS_DIR.read_dir().unwrap() {
|
||||
@ -234,11 +180,6 @@ fn kcl_samples_outputs(filter: Option<&str>) -> Vec<String> {
|
||||
// Skip hidden.
|
||||
continue;
|
||||
}
|
||||
if let Some(filter) = &filter {
|
||||
if !dir_name_str.starts_with(filter) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
eprintln!("Found expected KCL sample: {:?}", &dir_name_str);
|
||||
outputs.push(dir_name_str.into_owned());
|
||||
@ -352,10 +293,7 @@ fn generate_kcl_manifest(dir: &Path) -> Result<()> {
|
||||
|
||||
// Write the manifest.json
|
||||
let output_path = dir.join(MANIFEST_FILE);
|
||||
let manifest_json = serde_json::to_string_pretty(&manifest)?;
|
||||
|
||||
let mut file = fs::File::create(output_path.clone())?;
|
||||
file.write_all(manifest_json.as_bytes())?;
|
||||
expectorate::assert_contents(&output_path, &serde_json::to_string_pretty(&manifest).unwrap());
|
||||
|
||||
println!(
|
||||
"Manifest of {} items written to {}",
|
||||
@ -391,7 +329,7 @@ fn update_readme(dir: &Path, new_content: &str) -> Result<()> {
|
||||
let updated_content = format!("{}{}\n", &content[..position], new_content);
|
||||
|
||||
// Write the modified content back to the file
|
||||
std::fs::write(readme_path, updated_content)?;
|
||||
expectorate::assert_contents(&readme_path, &updated_content);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
Reference in New Issue
Block a user