From 72c8da94a336680ec7c8ab21a9ad06b528010cf4 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Tue, 18 Apr 2023 22:38:18 -0400 Subject: [PATCH 1/2] Hook the integration tests into rust's test framework. Instead of using a hacked-together shell script, use rust's test framework to do the comparison. --- Cargo.toml | 7 ++++++ Makefile | 6 ++++- build.rs | 58 ++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 8 ++++++ tests/test_loader.rs | 1 + tests/test_template | 17 +++++++++++++ 6 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 build.rs create mode 100644 src/lib.rs create mode 100644 tests/test_loader.rs create mode 100644 tests/test_template diff --git a/Cargo.toml b/Cargo.toml index 7041f507..53b07955 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,10 @@ edition = "2021" license = "0BSD" default-run = "toy" +[lib] +name = "organic" +path = "src/lib.rs" + [[bin]] name = "toy" path = "src/main.rs" @@ -23,6 +27,9 @@ tracing = "0.1.37" tracing-opentelemetry = "0.17.2" tracing-subscriber = {version="0.3.16", features=["env-filter"]} +[build-dependencies] +walkdir = "2.3.3" + [features] default = ["compare"] compare = [] diff --git a/Makefile b/Makefile index 48749fde..aa85f7b6 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,11 @@ clean: .PHONY: test test: -> cargo test --bin toy +> cargo test --lib + +.PHONY: integrationtest +integrationtest: +> cargo test --no-fail-fast --test test_loader .PHONY: run run: diff --git a/build.rs b/build.rs new file mode 100644 index 00000000..3a56b09b --- /dev/null +++ b/build.rs @@ -0,0 +1,58 @@ +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::Path; +use walkdir::WalkDir; + +fn main() { + let out_dir = env::var("OUT_DIR").unwrap(); + let destination = Path::new(&out_dir).join("tests.rs"); + let mut test_file = File::create(&destination).unwrap(); + + write_header(&mut test_file); + + let test_files = WalkDir::new("org_mode_samples") + .into_iter() + .filter(|e| match e { + Ok(dir_entry) => { + dir_entry.file_type().is_file() + && Path::new(dir_entry.file_name()) + .extension() + .map(|ext| ext.to_ascii_lowercase() == "org") + .unwrap_or(false) + } + Err(_) => true, + }).collect::, _>>().unwrap(); + for test in test_files { + write_test(&mut test_file, &test); + } + +} + +fn write_test(test_file: &mut File, test: &walkdir::DirEntry) { + let test_name = test.path().strip_prefix("org_mode_samples/").expect("Paths should be under org_mode_samples/").to_string_lossy().to_lowercase().strip_suffix(".org").expect("Should have .org extension").replace("/", "_"); + + + write!( + test_file, + include_str!("./tests/test_template"), + name = test_name, + path = test.path().display() + ) + .unwrap(); +} + +fn write_header(test_file: &mut File) { + write!( + test_file, + r#" +#[feature(exit_status_error)] +use organic::compare_document; +use organic::document; +use organic::emacs_parse_org_document; +use organic::sexp; + +"# + ) + .unwrap(); +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 00000000..fbcf7914 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,8 @@ +#![feature(round_char_boundary)] +#![feature(exit_status_error)] +mod parser; +mod compare; +pub use parser::*; +pub use compare::emacs_parse_org_document; +pub use compare::sexp; +pub use compare::compare_document; diff --git a/tests/test_loader.rs b/tests/test_loader.rs new file mode 100644 index 00000000..0471b27a --- /dev/null +++ b/tests/test_loader.rs @@ -0,0 +1 @@ +include!(concat!(env!("OUT_DIR"), "/tests.rs")); diff --git a/tests/test_template b/tests/test_template new file mode 100644 index 00000000..ebe8f9e0 --- /dev/null +++ b/tests/test_template @@ -0,0 +1,17 @@ +#[test] +fn {name}() {{ + let todo_org_path = "{path}"; + let org_contents = std::fs::read_to_string(todo_org_path).expect("Read org file."); + let org_sexp = emacs_parse_org_document(todo_org_path).expect("Use emacs to parse org file."); + println!("{{}}", org_sexp); + let (_remaining, parsed_sexp) = sexp(org_sexp.as_str()).expect("Sexp Parse failure"); + let (remaining, rust_parsed) = document(org_contents.as_str()).expect("Org Parse failure"); + println!("{{:#?}}", rust_parsed); + let diff_result = + compare_document(&parsed_sexp, &rust_parsed).expect("Compare parsed documents."); + diff_result + .print() + .expect("Print document parse tree diff."); + assert!(!diff_result.is_bad()); + assert_eq!(remaining, ""); +}} From b0965bebe6687fde75f4adeb0057c0934d8a6440 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Tue, 18 Apr 2023 23:53:06 -0400 Subject: [PATCH 2/2] Remove old script for invoking the tests. --- scripts/compare_parse_all.bash | 36 ---------------------------------- 1 file changed, 36 deletions(-) delete mode 100755 scripts/compare_parse_all.bash diff --git a/scripts/compare_parse_all.bash b/scripts/compare_parse_all.bash deleted file mode 100755 index fc8a8416..00000000 --- a/scripts/compare_parse_all.bash +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash -# -# Check that the official org-mode parser and this implementation of an org-mode parser agree on how the sample org-mode documents should be parsed. -set -euo pipefail -IFS=$'\n\t' -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -cd "$DIR" - -: ${org_dir:="$DIR/../org_mode_samples"} -: ${compare_bin:="$DIR/../target/debug/org_compare"} - -test_files=$(find $org_dir -type f -name '*.org' | sort) - -cargo build --bin org_compare - -pass=0 -fail=0 - - -while read test_file; do - print_path=$(realpath --relative-to="$org_dir" "$test_file") - set +e - diff_results=$("$compare_bin" "$test_file") - diff_status=$? - set -e - if [ $diff_status -eq 0 ]; then - echo "GOOD $print_path" - pass=$((pass + 1)) - else - echo "BAD $print_path" - fail=$((fail + 1)) - fi -done<<<"$test_files" - -total=$((pass + fail)) -(>&2 echo "Tests passed: $pass/$total")