Test org_mode_samples both with and without alphabetical lists enabled.

This commit is contained in:
Tom Alexander 2023-09-29 15:30:38 -04:00
parent f1261ddce8
commit 2012e5a6d5
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
7 changed files with 109 additions and 23 deletions

View File

@ -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,
}
}

5
notes/test_names.org Normal file
View File

@ -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.

View File

@ -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<P: AsRef<Path>>(org_path: P) -> Result<(), Box<dyn st
Ok(())
}
pub fn run_anonymous_compare_with_settings<P: AsRef<str>>(
org_contents: P,
global_settings: &GlobalSettings,
) -> Result<(), Box<dyn std::error::Error>> {
// 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(())
}

View File

@ -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;

View File

@ -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<C>(
file_contents: C,
) -> Result<String, Box<dyn std::error::Error>>
@ -33,6 +46,41 @@ where
Ok(String::from_utf8(org_sexp)?)
}
pub fn emacs_parse_anonymous_org_document_with_settings<C>(
file_contents: C,
global_settings: &GlobalSettings,
) -> Result<String, Box<dyn std::error::Error>>
where
C: AsRef<str>,
{
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<P>(file_path: P) -> Result<String, Box<dyn std::error::Error>>
where
P: AsRef<Path>,

View File

@ -1,2 +1,5 @@
#[cfg(feature = "compare")]
#![cfg(feature = "compare")]
#[feature(exit_status_error)]
include!(concat!(env!("OUT_DIR"), "/tests.rs"));

View File

@ -1,7 +1,22 @@
{expect_fail}
#[test]
fn {name}() -> Result<(), Box<dyn std::error::Error>> {{
fn autogen_{name}() -> Result<(), Box<dyn std::error::Error>> {{
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<dyn std::error::Error>> {{
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(())
}}