BytesAt command tests

This commit is contained in:
simon-curtis 2024-10-10 23:13:07 +01:00 committed by Simon Curtis
parent cd6ff56d04
commit b99d8c1016
6 changed files with 93 additions and 31 deletions

View File

@ -43,7 +43,12 @@ mod test_examples {
signature.operates_on_cell_paths(),
),
);
check_example_evaluates_to_expected_output(&example, cwd.as_path(), &mut engine_state);
check_example_evaluates_to_expected_output(
cmd.name(),
&example,
cwd.as_path(),
&mut engine_state,
);
}
check_all_signature_input_output_types_entries_have_examples(

View File

@ -139,6 +139,7 @@ pub fn eval_block(
}
pub fn check_example_evaluates_to_expected_output(
cmd_name: &str,
example: &Example,
cwd: &std::path::Path,
engine_state: &mut Box<EngineState>,
@ -159,11 +160,19 @@ pub fn check_example_evaluates_to_expected_output(
// If the command you are testing requires to compare another case, then
// you need to define its equality in the Value struct
if let Some(expected) = example.result.as_ref() {
assert_eq!(
DebuggableValue(&result),
DebuggableValue(expected),
"The example result differs from the expected value",
)
let expected = DebuggableValue(expected);
let result = DebuggableValue(&result);
if result != expected {
panic!(
"\x1b[31mError:\x1b[0m The result of example \x1b[34m'{}'\x1b[0m for the command \x1b[34m'{}'\x1b[0m differs from the expected value.\n\n\
Expected: {:?}\n\
Actual: {:?}\n",
example.description,
cmd_name,
expected,
result
);
}
}
}

View File

@ -44,7 +44,12 @@ mod test_examples {
signature.operates_on_cell_paths(),
),
);
check_example_evaluates_to_expected_output(&example, cwd.as_path(), &mut engine_state);
check_example_evaluates_to_expected_output(
cmd.name(),
&example,
cwd.as_path(),
&mut engine_state,
);
}
check_all_signature_input_output_types_entries_have_examples(

View File

@ -46,6 +46,7 @@ impl Command for BytesAt {
(Type::table(), Type::table()),
(Type::record(), Type::record()),
])
.allow_variants_without_examples(true)
.required("range", SyntaxShape::Range, "The range to get bytes.")
.rest(
"rest",
@ -95,37 +96,46 @@ impl Command for BytesAt {
fn examples(&self) -> Vec<Example> {
vec![
Example {
description: "Get a subbytes `0x[10 01]` from the bytes `0x[33 44 55 10 01 13]`",
example: " 0x[33 44 55 10 01 13] | bytes at 3..<4",
result: Some(Value::test_binary(vec![0x10])),
},
Example {
description: "Get a subbytes `0x[10 01 13]` from the bytes `0x[33 44 55 10 01 13]`",
example: " 0x[33 44 55 10 01 13] | bytes at 3..6",
result: Some(Value::test_binary(vec![0x10, 0x01, 0x13])),
},
Example {
description: "Get the remaining characters from a starting index",
example: " { data: 0x[33 44 55 10 01 13] } | bytes at 3.. data",
description: "Extract bytes starting from a specific index",
example: "{ data: 0x[33 44 55 10 01 13 10] } | bytes at 3.. data",
result: Some(Value::test_record(record! {
"data" => Value::test_binary(vec![0x10, 0x01, 0x13]),
"data" => Value::test_binary(vec![0x10, 0x01, 0x13, 0x10]),
})),
},
Example {
description: "Get the characters from the beginning until ending index",
example: " 0x[33 44 55 10 01 13] | bytes at ..<4",
description: "Slice out `0x[10 01 13]` from `0x[33 44 55 10 01 13]`",
example: "0x[33 44 55 10 01 13 10] | bytes at 3..6",
result: Some(Value::test_binary(vec![0x10, 0x01, 0x13, 0x10])),
},
Example {
description: "Extract bytes from the start up to a specific index",
example: "0x[33 44 55 10 01 13 10] | bytes at ..4",
result: Some(Value::test_binary(vec![0x33, 0x44, 0x55, 0x10, 0x01])),
},
Example {
description: "Extract byte `0x[10]` using an exclusive end index",
example: "0x[33 44 55 10 01 13 10] | bytes at 3..<4",
result: Some(Value::test_binary(vec![0x10])),
},
Example {
description: "Extract bytes up to a negative index (inclusive)",
example: "0x[33 44 55 10 01 13 10] | bytes at ..-4",
result: Some(Value::test_binary(vec![0x33, 0x44, 0x55, 0x10])),
},
Example {
description:
"Or the characters from the beginning until ending index inside a table",
example: r#" [[ColA ColB ColC]; [0x[11 12 13] 0x[14 15 16] 0x[17 18 19]]] | bytes at 1.. ColB ColC"#,
description: "Slice bytes across multiple table columns",
example: r#"[[ColA ColB ColC]; [0x[11 12 13] 0x[14 15 16] 0x[17 18 19]]] | bytes at 1.. ColB ColC"#,
result: Some(Value::test_list(vec![Value::test_record(record! {
"ColA" => Value::test_binary(vec![0x11, 0x12, 0x13]),
"ColB" => Value::test_binary(vec![0x15, 0x16]),
"ColC" => Value::test_binary(vec![0x18, 0x19]),
})])),
},
Example {
description: "Extract the last three bytes using a negative start index",
example: "0x[33 44 55 10 01 13 10] | bytes at (-3)..",
result: Some(Value::test_binary(vec![0x01, 0x13, 0x10])),
},
]
}
}
@ -155,10 +165,6 @@ fn handle_byte_stream(
engine_state: &EngineState,
) -> Result<PipelineData, ShellError> {
let idxs = args.indexes;
if idxs.0 >= idxs.1 {
return Ok(PipelineData::empty());
}
match stream.reader() {
Some(reader) => {
let iter = reader.bytes();
@ -231,3 +237,35 @@ fn read_stream(
PipelineData::ByteStream(stream, metadata)
}
#[cfg(test)]
mod tests {
use super::*;
use nu_test_support::nu;
#[test]
fn test_examples() {
use crate::test_examples;
test_examples(BytesAt {})
}
#[test]
fn returns_error_for_relative_range_on_infinite_stream() {
let actual = nu!("nu --testbin iecho 3 | bytes at ..-3");
assert!(
actual.err.contains(
"Negative range values cannot be used with streams that don't specify a length"
),
"Expected error message for negative range with infinite stream"
);
}
#[test]
fn returns_bytes_for_fixed_range_on_infinite_stream() {
let actual = nu!("nu --testbin iecho 3 | bytes at ..10 | decode");
assert_eq!(
actual.out, "33333",
"Expected bytes from index 1 to 10, but got different output"
);
}
}

View File

@ -61,7 +61,12 @@ mod test_examples {
signature.operates_on_cell_paths(),
),
);
check_example_evaluates_to_expected_output(&example, cwd.as_path(), &mut engine_state);
check_example_evaluates_to_expected_output(
cmd.name(),
&example,
cwd.as_path(),
&mut engine_state,
);
}
check_all_signature_input_output_types_entries_have_examples(

View File

@ -25,7 +25,7 @@ pub fn run_test(input: &str, expected: &str) -> TestResult {
let mut file = NamedTempFile::new()?;
let name = file.path();
let mut cmd = Command::cargo_bin("nu")?;
let mut cmd: Command = Command::cargo_bin("nu")?;
cmd.arg("--no-std-lib");
cmd.arg("--no-config-file");
cmd.arg(name);