mirror of
https://github.com/nushell/nushell
synced 2024-12-31 23:39:00 +00:00
aded2c1937
# Description This is a pretty heavy refactor of the parser to support multiple parser errors. It has a few issues we should address before landing: - [x] In some cases, error quality has gotten worse `1 / "bob"` for example - [x] if/else isn't currently parsing correctly - probably others # User-Facing Changes This may have error quality degradation as we adjust to the new error reporting mechanism. # Tests + Formatting Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass - `cargo run -- crates/nu-utils/standard_library/tests.nu` to run the tests for the standard library > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` # After Submitting If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date.
89 lines
3.2 KiB
Rust
89 lines
3.2 KiB
Rust
#![cfg(test)]
|
|
|
|
//use nu_parser::ParseError;
|
|
use nu_parser::*;
|
|
use nu_protocol::{
|
|
//ast::{Expr, Expression, PipelineElement},
|
|
ast::{Expr, PipelineElement},
|
|
//engine::{Command, EngineState, Stack, StateWorkingSet},
|
|
engine::{EngineState, StateWorkingSet},
|
|
//Signature, SyntaxShape,
|
|
};
|
|
|
|
pub fn do_test(test: &[u8], expected: &str, error_contains: Option<&str>) {
|
|
let engine_state = EngineState::new();
|
|
let mut working_set = StateWorkingSet::new(&engine_state);
|
|
|
|
let block = parse(&mut working_set, None, test, true, &[]);
|
|
|
|
match working_set.parse_errors.first() {
|
|
None => {
|
|
assert_eq!(block.len(), 1);
|
|
let expressions = &block[0];
|
|
assert_eq!(expressions.len(), 1);
|
|
if let PipelineElement::Expression(_, expr) = &expressions[0] {
|
|
assert_eq!(expr.expr, Expr::String(expected.to_string()))
|
|
} else {
|
|
panic!("Not an expression")
|
|
}
|
|
}
|
|
Some(pev) => match error_contains {
|
|
None => {
|
|
panic!("Err:{pev:#?}");
|
|
}
|
|
Some(contains_string) => {
|
|
let full_err = format!("{pev:#?}");
|
|
assert!(
|
|
full_err.contains(contains_string),
|
|
"Expected error containing {contains_string}, instead got {full_err}"
|
|
);
|
|
}
|
|
},
|
|
}
|
|
}
|
|
|
|
// cases that all should work
|
|
#[test]
|
|
pub fn unicode_escapes_in_strings() {
|
|
pub struct Tc(&'static [u8], &'static str);
|
|
|
|
let test_vec = vec![
|
|
Tc(b"\"hello \\u{6e}\\u{000075}\\u{073}hell\"", "hello nushell"),
|
|
// template: Tc(br#""<string literal without #'s>"", "<Rust literal comparand>")
|
|
//deprecated Tc(br#""\u006enu\u0075\u0073\u0073""#, "nnuuss"),
|
|
Tc(br#""hello \u{6e}\u{000075}\u{073}hell""#, "hello nushell"),
|
|
Tc(br#""\u{39}8\u{10ffff}""#, "98\u{10ffff}"),
|
|
Tc(br#""abc\u{41}""#, "abcA"), // at end of string
|
|
Tc(br#""\u{41}abc""#, "Aabc"), // at start of string
|
|
Tc(br#""\u{a}""#, "\n"), // single digit
|
|
];
|
|
|
|
for tci in test_vec {
|
|
println!("Expecting: {}", tci.1);
|
|
do_test(tci.0, tci.1, None);
|
|
}
|
|
}
|
|
|
|
// cases that all should fail (in expected way)
|
|
#[test]
|
|
pub fn unicode_escapes_in_strings_expected_failures() {
|
|
// input, substring of expected failure
|
|
pub struct Tc(&'static [u8], &'static str);
|
|
|
|
let test_vec = vec![
|
|
// template: Tc(br#""<string literal without #'s>"", "<pattern in expected error>")
|
|
//deprecated Tc(br#""\u06e""#, "any shape"), // 4digit too short, next char is EOF
|
|
//deprecatedTc(br#""\u06ex""#, "any shape"), // 4digit too short, next char is non-hex-digit
|
|
Tc(br#""hello \u{6e""#, "missing '}'"), // extended, missing close delim
|
|
Tc(
|
|
br#""\u{39}8\u{000000000000000000000000000000000000000000000037}""#,
|
|
"must be 1-6 hex digits",
|
|
), // hex too long, but small value
|
|
Tc(br#""\u{110000}""#, "max value 10FFF"), // max unicode <= 0x10ffff
|
|
];
|
|
|
|
for tci in test_vec {
|
|
println!("Expecting failure containing: {}", tci.1);
|
|
do_test(tci.0, "--success not expected--", Some(tci.1));
|
|
}
|
|
}
|