From 2012e5a6d5c4840e647513a66b84f448ed8f9883 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Fri, 29 Sep 2023 15:30:38 -0400 Subject: [PATCH] Test org_mode_samples both with and without alphabetical lists enabled. --- build.rs | 27 ++++++------------------ notes/test_names.org | 5 +++++ src/compare/compare.rs | 29 +++++++++++++++++++++++++ src/compare/mod.rs | 1 + src/compare/parse.rs | 48 ++++++++++++++++++++++++++++++++++++++++++ tests/test_loader.rs | 5 ++++- tests/test_template | 17 ++++++++++++++- 7 files changed, 109 insertions(+), 23 deletions(-) create mode 100644 notes/test_names.org diff --git a/build.rs b/build.rs index 6fbdbe8..307b9f4 100644 --- a/build.rs +++ b/build.rs @@ -19,8 +19,6 @@ fn main() { // Re-generate the tests if any org-mode files change println!("cargo:rerun-if-changed=org_mode_samples"); - write_header(&mut test_file); - let test_files = WalkDir::new("org_mode_samples") .into_iter() .filter(|e| match e { @@ -54,28 +52,15 @@ fn write_test(test_file: &mut File, test: &walkdir::DirEntry) { .strip_suffix(".org") .expect("Should have .org extension") .replace("/", "_"); - let test_name = format!("autogen_{}", test_name); - if let Some(_reason) = is_expect_fail(test_name.as_str()) { - write!(test_file, "#[ignore]\n").unwrap(); - } write!( test_file, include_str!("./tests/test_template"), name = test_name, - path = test.path().display() - ) - .unwrap(); -} - -#[cfg(feature = "compare")] -fn write_header(test_file: &mut File) { - write!( - test_file, - r#" -#[feature(exit_status_error)] - -"# + path = test.path().display(), + expect_fail = is_expect_fail(test_name.as_str()) + .map(|_| "#[ignore]\n") + .unwrap_or("") ) .unwrap(); } @@ -83,8 +68,8 @@ fn write_header(test_file: &mut File) { #[cfg(feature = "compare")] fn is_expect_fail(name: &str) -> Option<&str> { match name { - "autogen_greater_element_drawer_drawer_with_headline_inside" => Some("Apparently lines with :end: become their own paragraph. This odd behavior needs to be investigated more."), - "autogen_element_container_priority_footnote_definition_dynamic_block" => Some("Apparently broken begin lines become their own paragraph."), + "greater_element_drawer_drawer_with_headline_inside" => Some("Apparently lines with :end: become their own paragraph. This odd behavior needs to be investigated more."), + "element_container_priority_footnote_definition_dynamic_block" => Some("Apparently broken begin lines become their own paragraph."), _ => None, } } diff --git a/notes/test_names.org b/notes/test_names.org new file mode 100644 index 0000000..cf2bc18 --- /dev/null +++ b/notes/test_names.org @@ -0,0 +1,5 @@ +* Autogen tests +The autogen tests are the tests automatically generated to compare the output of Organic vs the upstream Emacs Org-mode parser using the sample documents in the =org_mode_samples= folder. They will have a prefix based on the settings for each test. + +- No prefix :: The test is run with the default settings (The upstream Emacs Org-mode determines the default settings) +- la :: Short for "list alphabetic". Enables alphabetic plain lists. diff --git a/src/compare/compare.rs b/src/compare/compare.rs index 5d6cd46..d887d24 100644 --- a/src/compare/compare.rs +++ b/src/compare/compare.rs @@ -2,6 +2,7 @@ use std::path::Path; use crate::compare::diff::compare_document; use crate::compare::parse::emacs_parse_anonymous_org_document; +use crate::compare::parse::emacs_parse_anonymous_org_document_with_settings; use crate::compare::parse::emacs_parse_file_org_document; use crate::compare::parse::get_emacs_version; use crate::compare::parse::get_org_mode_version; @@ -75,3 +76,31 @@ pub fn run_compare_on_file>(org_path: P) -> Result<(), Box>( + org_contents: P, + global_settings: &GlobalSettings, +) -> Result<(), Box> { + // TODO: This is a work-around to pretend that dos line endings do not exist. It would be better to handle the difference in line endings. + let org_contents = org_contents.as_ref().replace("\r\n", "\n"); + let org_contents = org_contents.as_str(); + eprintln!("Using emacs version: {}", get_emacs_version()?.trim()); + eprintln!("Using org-mode version: {}", get_org_mode_version()?.trim()); + let rust_parsed = parse_with_settings(org_contents, global_settings)?; + let org_sexp = emacs_parse_anonymous_org_document_with_settings(org_contents, global_settings)?; + let (_remaining, parsed_sexp) = sexp(org_sexp.as_str()).map_err(|e| e.to_string())?; + + println!("{}\n\n\n", org_contents); + println!("{}", org_sexp); + println!("{:#?}", rust_parsed); + + // We do the diffing after printing out both parsed forms in case the diffing panics + let diff_result = compare_document(&parsed_sexp, &rust_parsed)?; + diff_result.print(org_contents)?; + + if diff_result.is_bad() { + Err("Diff results do not match.")?; + } + + Ok(()) +} diff --git a/src/compare/mod.rs b/src/compare/mod.rs index 5c729a8..f901679 100644 --- a/src/compare/mod.rs +++ b/src/compare/mod.rs @@ -5,4 +5,5 @@ mod parse; mod sexp; mod util; pub use compare::run_anonymous_compare; +pub use compare::run_anonymous_compare_with_settings; pub use compare::run_compare_on_file; diff --git a/src/compare/parse.rs b/src/compare/parse.rs index 6170ce7..f60ef2e 100644 --- a/src/compare/parse.rs +++ b/src/compare/parse.rs @@ -1,6 +1,19 @@ use std::path::Path; use std::process::Command; +use crate::GlobalSettings; + +/// Generate elisp to configure org-mode parsing settings +/// +/// Currently only org-list-allow-alphabetical is supported. +fn global_settings_elisp(global_settings: &GlobalSettings) -> String { + let mut ret = "".to_owned(); + if global_settings.list_allow_alphabetical { + ret += "(setq org-list-allow-alphabetical t)\n" + } + ret +} + pub fn emacs_parse_anonymous_org_document( file_contents: C, ) -> Result> @@ -33,6 +46,41 @@ where Ok(String::from_utf8(org_sexp)?) } +pub fn emacs_parse_anonymous_org_document_with_settings( + file_contents: C, + global_settings: &GlobalSettings, +) -> Result> +where + C: AsRef, +{ + let escaped_file_contents = escape_elisp_string(file_contents); + let elisp_script = format!( + r#"(progn + (erase-buffer) + (require 'org) + (defun org-table-align () t) + (insert "{escaped_file_contents}") + {global_settings} + (org-mode) + (message "%s" (pp-to-string (org-element-parse-buffer))) +)"#, + escaped_file_contents = escaped_file_contents, + global_settings = global_settings_elisp(global_settings) + ); + let mut cmd = Command::new("emacs"); + let cmd = cmd + .arg("-q") + .arg("--no-site-file") + .arg("--no-splash") + .arg("--batch") + .arg("--eval") + .arg(elisp_script); + let out = cmd.output()?; + out.status.exit_ok()?; + let org_sexp = out.stderr; + Ok(String::from_utf8(org_sexp)?) +} + pub fn emacs_parse_file_org_document

(file_path: P) -> Result> where P: AsRef, diff --git a/tests/test_loader.rs b/tests/test_loader.rs index 9d63cc1..076f485 100644 --- a/tests/test_loader.rs +++ b/tests/test_loader.rs @@ -1,2 +1,5 @@ -#[cfg(feature = "compare")] +#![cfg(feature = "compare")] + +#[feature(exit_status_error)] + include!(concat!(env!("OUT_DIR"), "/tests.rs")); diff --git a/tests/test_template b/tests/test_template index 4454eb9..dd1b569 100644 --- a/tests/test_template +++ b/tests/test_template @@ -1,7 +1,22 @@ +{expect_fail} #[test] -fn {name}() -> Result<(), Box> {{ +fn autogen_{name}() -> Result<(), Box> {{ let org_path = "{path}"; let org_contents = std::fs::read_to_string(org_path).expect("Read org file."); organic::compare::run_anonymous_compare(org_contents.as_str())?; Ok(()) }} + +{expect_fail} +#[test] +fn autogen_la_{name}() -> Result<(), Box> {{ + let org_path = "{path}"; + let org_contents = std::fs::read_to_string(org_path).expect("Read org file."); + let global_settings = {{ + let mut global_settings = organic::GlobalSettings::default(); + global_settings.list_allow_alphabetical = true; + global_settings + }}; + organic::compare::run_anonymous_compare_with_settings(org_contents.as_str(), &global_settings)?; + Ok(()) +}}