Progress on comparing properties in the wasm_compare macro.

This commit is contained in:
Tom Alexander 2023-12-27 15:58:31 -05:00
parent 5f1668702a
commit 5b02c21ebf
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
4 changed files with 69 additions and 6 deletions

View File

@ -16,3 +16,4 @@ pub(crate) use compare_field::EmacsField;
pub(crate) use elisp_fact::ElispFact; pub(crate) use elisp_fact::ElispFact;
pub use sexp::sexp; pub use sexp::sexp;
pub use sexp::Token; pub use sexp::Token;
pub(crate) use util::get_property_quoted_string;

View File

@ -18,7 +18,7 @@ pub struct WasmDocument<'s, 'p> {
additional_properties: Vec<(String, &'s str)>, additional_properties: Vec<(String, &'s str)>,
pub(crate) children: Vec<WasmAstNode<'s, 'p>>, pub(crate) children: Vec<WasmAstNode<'s, 'p>>,
category: Option<&'p str>, category: Option<&'p str>,
path: Option<PathBuf>, pub(crate) path: Option<PathBuf>,
} }
to_wasm!( to_wasm!(

View File

@ -1,6 +1,7 @@
use std::borrow::Cow; use std::borrow::Cow;
use super::elisp_compare::WasmElispCompare; use super::elisp_compare::WasmElispCompare;
use crate::compare::get_property_quoted_string;
use crate::compare::ElispFact; use crate::compare::ElispFact;
use crate::compare::EmacsField; use crate::compare::EmacsField;
use crate::compare::Token; use crate::compare::Token;
@ -245,10 +246,39 @@ impl<'s, 'p> WasmElispCompare<'s, 'p> for WasmDocument<'s, 'p> {
( (
EmacsField::Required(":path"), EmacsField::Required(":path"),
|w| w.path.as_ref().and_then(|p| p.to_str()), |w| w.path.as_ref().and_then(|p| p.to_str()),
|| true wasm_compare_property_quoted_string
) )
); );
// todo: compare the rest
Ok(result) Ok(result)
} }
} }
fn wasm_compare_property_quoted_string<
'b,
's,
W,
WV: AsRef<str> + std::fmt::Debug,
WG: Fn(W) -> Option<WV>,
>(
_source: &'s str,
emacs: &'b Token<'s>,
wasm_node: W,
emacs_field: &str,
wasm_value_getter: WG,
) -> Result<WasmDiffResult<'s>, Box<dyn std::error::Error>> {
let mut result = WasmDiffResult::default();
let emacs_value = get_property_quoted_string(emacs, emacs_field)?;
let wasm_value = wasm_value_getter(wasm_node);
if wasm_value.as_ref().map(|s| s.as_ref()) != emacs_value.as_deref() {
result.status.push(WasmDiffStatus::Bad(
format!(
"Property mismatch. Property=({property}) Emacs=({emacs:?}) Wasm=({wasm:?}).",
property = emacs_field,
emacs = emacs_value,
wasm = wasm_value,
)
.into(),
))
}
Ok(result)
}

View File

@ -15,7 +15,7 @@ macro_rules! wasm_compare {
emacs_attributes_map.keys().map(|s| *s).collect(); emacs_attributes_map.keys().map(|s| *s).collect();
{ {
// Compare name // Compare name.
let wasm_name = $wasm.get_elisp_name(); let wasm_name = $wasm.get_elisp_name();
if emacs_name != wasm_name { if emacs_name != wasm_name {
@ -31,7 +31,7 @@ macro_rules! wasm_compare {
} }
{ {
// Compare children // Compare children.
result.extend(wasm_compare_list( result.extend(wasm_compare_list(
$source, $source,
emacs_list_iter, emacs_list_iter,
@ -40,7 +40,7 @@ macro_rules! wasm_compare {
} }
{ {
// Compare fields // Check for properties that are missing from the elisp node.
$( $(
match $emacs_field { match $emacs_field {
EmacsField::Required(name) if emacs_keys.contains(name) => { EmacsField::Required(name) if emacs_keys.contains(name) => {
@ -63,6 +63,38 @@ macro_rules! wasm_compare {
)* )*
} }
{
// Check for elisp properties that were not compared.
if !emacs_keys.is_empty() {
let unexpected_keys: Vec<&str> = emacs_keys.into_iter().collect();
let unexpected_keys = unexpected_keys.join(", ");
result.status.push(WasmDiffStatus::Bad(
format!(
"Emacs node had extra field(s): ({field_names}).",
field_names = unexpected_keys,
)
.into(),
));
}
}
{
// Compare properties.
$(
let emacs_name = match $emacs_field {
EmacsField::Required(name) => {
name
},
EmacsField::Optional(name) => {
name
},
};
let result = $compare_fn($source, $emacs, $wasm, emacs_name, $wasm_value_getter)?;
// TODO: record this result.
)*
}
result result
}}; }};
} }