mirror of
https://github.com/nushell/nushell.git
synced 2024-12-12 18:20:55 +01:00
adf38c7c76
# Description I thought about bringing `nu_plugin_msgpack` in, but that is MPL with a clause that prevents other licenses, so rather than adapt that code I decided to take a crack at just doing it straight from `rmp` to `Value` without any `rmpv` in the middle. It seems like it's probably faster, though I can't say for sure how much with the plugin overhead. @IanManske I started on a `Read` implementation for `RawStream` but just specialized to `from msgpack` here, but I'm thinking after release maybe we can polish it up and make it a real one. It works! # User-Facing Changes New commands: - `from msgpack` - `from msgpackz` - `to msgpack` - `to msgpackz` # Tests + Formatting Pretty thorough tests added for the format deserialization, with a roundtrip for serialization. Some example tests too for both `from msgpack` and `to msgpack`. - 🟢 `toolkit fmt` - 🟢 `toolkit clippy` - 🟢 `toolkit test` - 🟢 `toolkit test stdlib` # After Submitting - [ ] update release notes
160 lines
4.1 KiB
Rust
160 lines
4.1 KiB
Rust
use nu_test_support::{nu, playground::Playground};
|
|
use pretty_assertions::assert_eq;
|
|
|
|
fn msgpack_test(fixture_name: &str, commands: Option<&str>) -> nu_test_support::Outcome {
|
|
let path_to_generate_nu = nu_test_support::fs::fixtures()
|
|
.join("formats")
|
|
.join("msgpack")
|
|
.join("generate.nu");
|
|
|
|
let mut outcome = None;
|
|
Playground::setup(&format!("msgpack test {}", fixture_name), |dirs, _| {
|
|
assert!(nu!(
|
|
cwd: dirs.test(),
|
|
format!(
|
|
"nu -n '{}' '{}'",
|
|
path_to_generate_nu.display(),
|
|
fixture_name
|
|
),
|
|
)
|
|
.status
|
|
.success());
|
|
|
|
outcome = Some(nu!(
|
|
cwd: dirs.test(),
|
|
collapse_output: false,
|
|
commands.map(|c| c.to_owned()).unwrap_or_else(|| format!("open {fixture_name}.msgpack"))
|
|
));
|
|
});
|
|
outcome.expect("failed to get outcome")
|
|
}
|
|
|
|
fn msgpack_nuon_test(fixture_name: &str, opts: &str) {
|
|
let path_to_nuon = nu_test_support::fs::fixtures()
|
|
.join("formats")
|
|
.join("msgpack")
|
|
.join(format!("{fixture_name}.nuon"));
|
|
|
|
let sample_nuon = std::fs::read_to_string(path_to_nuon).expect("failed to open nuon file");
|
|
|
|
let outcome = msgpack_test(
|
|
fixture_name,
|
|
Some(&format!(
|
|
"open --raw {fixture_name}.msgpack | from msgpack {opts} | to nuon --indent 4"
|
|
)),
|
|
);
|
|
|
|
assert!(outcome.status.success());
|
|
assert!(outcome.err.is_empty());
|
|
assert_eq!(
|
|
sample_nuon.replace("\r\n", "\n"),
|
|
outcome.out.replace("\r\n", "\n")
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn sample() {
|
|
msgpack_nuon_test("sample", "");
|
|
}
|
|
|
|
#[test]
|
|
fn sample_roundtrip() {
|
|
let path_to_sample_nuon = nu_test_support::fs::fixtures()
|
|
.join("formats")
|
|
.join("msgpack")
|
|
.join("sample.nuon");
|
|
|
|
let sample_nuon =
|
|
std::fs::read_to_string(&path_to_sample_nuon).expect("failed to open sample.nuon");
|
|
|
|
let outcome = nu!(
|
|
collapse_output: false,
|
|
format!(
|
|
"open '{}' | to msgpack | from msgpack | to nuon --indent 4",
|
|
path_to_sample_nuon.display()
|
|
)
|
|
);
|
|
|
|
assert!(outcome.status.success());
|
|
assert!(outcome.err.is_empty());
|
|
assert_eq!(
|
|
sample_nuon.replace("\r\n", "\n"),
|
|
outcome.out.replace("\r\n", "\n")
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn objects() {
|
|
msgpack_nuon_test("objects", "--objects");
|
|
}
|
|
|
|
#[test]
|
|
fn max_depth() {
|
|
let outcome = msgpack_test("max-depth", None);
|
|
assert!(!outcome.status.success());
|
|
assert!(outcome.err.contains("exceeded depth limit"));
|
|
}
|
|
|
|
#[test]
|
|
fn non_utf8() {
|
|
let outcome = msgpack_test("non-utf8", None);
|
|
assert!(!outcome.status.success());
|
|
assert!(outcome.err.contains("utf-8"));
|
|
}
|
|
|
|
#[test]
|
|
fn empty() {
|
|
let outcome = msgpack_test("empty", None);
|
|
assert!(!outcome.status.success());
|
|
assert!(outcome.err.contains("fill whole buffer"));
|
|
}
|
|
|
|
#[test]
|
|
fn eof() {
|
|
let outcome = msgpack_test("eof", None);
|
|
assert!(!outcome.status.success());
|
|
assert!(outcome.err.contains("fill whole buffer"));
|
|
}
|
|
|
|
#[test]
|
|
fn after_eof() {
|
|
let outcome = msgpack_test("after-eof", None);
|
|
assert!(!outcome.status.success());
|
|
assert!(outcome.err.contains("after end of"));
|
|
}
|
|
|
|
#[test]
|
|
fn reserved() {
|
|
let outcome = msgpack_test("reserved", None);
|
|
assert!(!outcome.status.success());
|
|
assert!(outcome.err.contains("Reserved"));
|
|
}
|
|
|
|
#[test]
|
|
fn u64_too_large() {
|
|
let outcome = msgpack_test("u64-too-large", None);
|
|
assert!(!outcome.status.success());
|
|
assert!(outcome.err.contains("integer too big"));
|
|
}
|
|
|
|
#[test]
|
|
fn non_string_map_key() {
|
|
let outcome = msgpack_test("non-string-map-key", None);
|
|
assert!(!outcome.status.success());
|
|
assert!(outcome.err.contains("string key"));
|
|
}
|
|
|
|
#[test]
|
|
fn timestamp_wrong_length() {
|
|
let outcome = msgpack_test("timestamp-wrong-length", None);
|
|
assert!(!outcome.status.success());
|
|
assert!(outcome.err.contains("Unknown MessagePack extension"));
|
|
}
|
|
|
|
#[test]
|
|
fn other_extension_type() {
|
|
let outcome = msgpack_test("other-extension-type", None);
|
|
assert!(!outcome.status.success());
|
|
assert!(outcome.err.contains("Unknown MessagePack extension"));
|
|
}
|