Fix #12280: replace difference crate with similar (#12282)

Fixes #12280.

# Description

This removes the dependency on the `difference` crate, which is
unmaintained, for `nu-plugin-test-support`. The `similar` crate
(Apache-2.0) is used instead, which is a bit larger and more complex,
but still suitable for a dev dep for tests. Also switched to use
`crossterm` for colors, since `similar` doesn't come with any terminal
pretty printing functionality.

# User-Facing Changes

None - output should be identical.

# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`
This commit is contained in:
Devyn Cairns 2024-03-25 19:13:12 -07:00 committed by GitHub
parent b2c5dc204a
commit efe1c99a3b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 39 additions and 17 deletions

9
Cargo.lock generated
View File

@ -1101,12 +1101,6 @@ version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
[[package]]
name = "difference"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
[[package]]
name = "difflib"
version = "0.4.0"
@ -3097,12 +3091,13 @@ dependencies = [
name = "nu-plugin-test-support"
version = "0.91.1"
dependencies = [
"difference",
"nu-ansi-term",
"nu-engine",
"nu-parser",
"nu-plugin",
"nu-protocol",
"serde",
"similar",
"typetag",
]

View File

@ -12,7 +12,8 @@ nu-engine = { path = "../nu-engine", version = "0.91.1", features = ["plugin"] }
nu-protocol = { path = "../nu-protocol", version = "0.91.1", features = ["plugin"] }
nu-parser = { path = "../nu-parser", version = "0.91.1", features = ["plugin"] }
nu-plugin = { path = "../nu-plugin", version = "0.91.1" }
difference = "2.0"
nu-ansi-term = { workspace = true }
similar = "2.4"
[dev-dependencies]
typetag = "0.2"

View File

@ -0,0 +1,27 @@
use std::fmt::Write;
use nu_ansi_term::{Color, Style};
use similar::{ChangeTag, TextDiff};
/// Generate a stylized diff of different lines between two strings
pub(crate) fn diff_by_line(old: &str, new: &str) -> String {
let mut out = String::new();
let diff = TextDiff::from_lines(old, new);
for change in diff.iter_all_changes() {
let style = match change.tag() {
ChangeTag::Equal => Style::new(),
ChangeTag::Delete => Color::Red.into(),
ChangeTag::Insert => Color::Green.into(),
};
let _ = write!(
out,
"{}{}",
style.paint(change.tag().to_string()),
style.paint(change.value()),
);
}
out
}

View File

@ -63,6 +63,7 @@
//! # test_lowercase().unwrap();
//! ```
mod diff;
mod fake_persistent_plugin;
mod fake_register;
mod plugin_test;

View File

@ -1,6 +1,6 @@
use std::{convert::Infallible, sync::Arc};
use difference::Changeset;
use nu_ansi_term::Style;
use nu_engine::eval_block;
use nu_parser::parse;
use nu_plugin::{Plugin, PluginCommand, PluginCustomValue, PluginSource};
@ -10,7 +10,7 @@ use nu_protocol::{
report_error_new, LabeledError, PipelineData, PluginExample, ShellError, Span, Value,
};
use crate::fake_register::fake_register;
use crate::{diff::diff_by_line, fake_register::fake_register};
/// An object through which plugins can be tested.
pub struct PluginTest {
@ -190,10 +190,11 @@ impl PluginTest {
let mut failed = false;
for example in examples {
let bold = Style::new().bold();
let mut failed_header = || {
failed = true;
eprintln!("\x1b[1mExample:\x1b[0m {}", example.example);
eprintln!("\x1b[1mDescription:\x1b[0m {}", example.description);
eprintln!("{} {}", bold.paint("Example:"), example.example);
eprintln!("{} {}", bold.paint("Description:"), example.description);
};
if let Some(expectation) = &example.result {
match self.eval(&example.example) {
@ -212,12 +213,9 @@ impl PluginTest {
// If they're not equal, print a diff of the debug format
let expectation_formatted = format!("{:#?}", expectation);
let value_formatted = format!("{:#?}", value);
let diff =
Changeset::new(&expectation_formatted, &value_formatted, "\n");
let diff = diff_by_line(&expectation_formatted, &value_formatted);
failed_header();
eprintln!("\x1b[1mResult:\x1b[0m {diff}");
} else {
println!("{:?}, {:?}", expectation, value);
eprintln!("{} {}", bold.paint("Result:"), diff);
}
}
Err(err) => {