104 lines
2.9 KiB
Rust
104 lines
2.9 KiB
Rust
use reconcile_text::{BuiltinTokenizer, Token, reconcile};
|
|
use test_case::{test_case, test_matrix};
|
|
|
|
#[test_matrix([
|
|
BuiltinTokenizer::Character,
|
|
BuiltinTokenizer::Line,
|
|
BuiltinTokenizer::Markdown,
|
|
BuiltinTokenizer::Word
|
|
])]
|
|
fn identical_edits_preserve_text(tokenizer: BuiltinTokenizer) {
|
|
let texts = [
|
|
"",
|
|
"a",
|
|
"b\n",
|
|
"\r\n\r\n",
|
|
"# Héllo\n\n- 世界\n",
|
|
"a a a\nb b b\n",
|
|
];
|
|
for parent in texts {
|
|
for updated in texts {
|
|
let input = updated.into();
|
|
assert_eq!(
|
|
reconcile(parent, &input, &input, &*tokenizer)
|
|
.apply()
|
|
.text(),
|
|
updated,
|
|
"tokenizer={tokenizer:?}, parent={parent:?}, updated={updated:?}",
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test_matrix([
|
|
BuiltinTokenizer::Character,
|
|
BuiltinTokenizer::Line,
|
|
BuiltinTokenizer::Markdown,
|
|
BuiltinTokenizer::Word
|
|
])]
|
|
fn identical_short_edits_preserve_text(tokenizer: BuiltinTokenizer) {
|
|
let mut texts = vec![String::new()];
|
|
let mut level = texts.clone();
|
|
for _ in 0..3 {
|
|
level = level
|
|
.iter()
|
|
.flat_map(|text| ['a', 'b', ' ', '\n'].map(|ch| format!("{text}{ch}")))
|
|
.collect();
|
|
texts.extend(level.iter().cloned());
|
|
}
|
|
|
|
for parent in &texts {
|
|
for updated in &texts {
|
|
let input = updated.into();
|
|
assert_eq!(
|
|
reconcile(parent, &input, &input, &*tokenizer)
|
|
.apply()
|
|
.text(),
|
|
*updated,
|
|
"tokenizer={tokenizer:?}, parent={parent:?}, updated={updated:?}",
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test_case("A", "a"; "lowercase")]
|
|
#[test_case("a", "A"; "uppercase")]
|
|
#[test_case("Hello WORLD", "HELLO world")]
|
|
#[test_case("X A", "x a\n")]
|
|
#[test_case("A", "new a"; "normalized_suffix")]
|
|
#[test_case("a old B", "A new b"; "normalized_prefix_and_suffix")]
|
|
fn identical_edits_preserve_original_spelling(parent: &str, updated: &str) {
|
|
let tokenizer = |text: &str| {
|
|
text.chars()
|
|
.map(|ch| Token::new(ch.to_ascii_lowercase(), ch.to_string(), false, false))
|
|
.collect()
|
|
};
|
|
let input = updated.into();
|
|
assert_eq!(
|
|
reconcile(parent, &input, &input, &tokenizer).apply().text(),
|
|
updated,
|
|
);
|
|
}
|
|
|
|
#[test_case("a", "\n\n", "a\n\n", "\n\n"; "deleted_prefix")]
|
|
#[test_case("a b", "\n\n", "b\n\n", "\n\n"; "partially_deleted_prefix")]
|
|
fn consecutive_markdown_insertions_preserve_text_in_both_orders(
|
|
parent: &str,
|
|
left: &str,
|
|
right: &str,
|
|
expected: &str,
|
|
) {
|
|
for (left, right) in [(left, right), (right, left)] {
|
|
assert_eq!(
|
|
reconcile(
|
|
parent,
|
|
&left.into(),
|
|
&right.into(),
|
|
&*BuiltinTokenizer::Markdown
|
|
)
|
|
.apply()
|
|
.text(),
|
|
expected,
|
|
);
|
|
}
|
|
}
|