mirror of
https://github.com/nushell/nushell
synced 2024-12-28 05:53:09 +00:00
Add some tests
This commit is contained in:
parent
2675ad9304
commit
4ef65f0983
2 changed files with 102 additions and 2 deletions
|
@ -13,4 +13,6 @@ pub enum ParseError {
|
|||
UnknownFlag(Span),
|
||||
MissingFlagParam(Span),
|
||||
ShortFlagBatchCantTakeArg(Span),
|
||||
MissingPositional(String, Span),
|
||||
MissingRequiredFlag(String, Span),
|
||||
}
|
||||
|
|
102
src/parser.rs
102
src/parser.rs
|
@ -3,7 +3,7 @@ use std::ops::{Index, IndexMut};
|
|||
use crate::{
|
||||
lex, lite_parse,
|
||||
parser_state::{Type, VarId},
|
||||
DeclId, LiteBlock, ParseError, ParserWorkingSet, Span,
|
||||
DeclId, LiteBlock, ParseError, ParserWorkingSet, Signature, Span,
|
||||
};
|
||||
|
||||
/// The syntactic shapes that values must match to be passed into a command. You can think of this as the type-checking that occurs when you call a function.
|
||||
|
@ -188,6 +188,23 @@ fn is_variable(bytes: &[u8]) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_call(command: Span, sig: &Signature, call: &Call) -> Option<ParseError> {
|
||||
if call.positional.len() < sig.required_positional.len() {
|
||||
let missing = &sig.required_positional[call.positional.len()];
|
||||
Some(ParseError::MissingPositional(missing.name.clone(), command))
|
||||
} else {
|
||||
for req_flag in sig.named.iter().filter(|x| x.required) {
|
||||
if call.named.iter().all(|(n, _)| n != &req_flag.long) {
|
||||
return Some(ParseError::MissingRequiredFlag(
|
||||
req_flag.long.clone(),
|
||||
command,
|
||||
));
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn span(spans: &[Span]) -> Span {
|
||||
let length = spans.len();
|
||||
|
||||
|
@ -341,6 +358,9 @@ impl ParserWorkingSet {
|
|||
arg_offset += 1;
|
||||
}
|
||||
|
||||
let err = check_call(spans[0], &sig, &call);
|
||||
error = error.or(err);
|
||||
|
||||
// FIXME: type unknown
|
||||
(
|
||||
Expression {
|
||||
|
@ -612,7 +632,7 @@ impl ParserWorkingSet {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::Signature;
|
||||
use crate::{ParseError, Signature};
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -652,4 +672,82 @@ mod tests {
|
|||
})
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn parse_call_missing_flag_arg() {
|
||||
let mut working_set = ParserWorkingSet::new(None);
|
||||
|
||||
let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'));
|
||||
working_set.add_decl((b"foo").to_vec(), sig);
|
||||
|
||||
let (_, err) = working_set.parse_source(b"foo --jazz");
|
||||
assert!(matches!(err, Some(ParseError::MissingFlagParam(..))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn parse_call_missing_short_flag_arg() {
|
||||
let mut working_set = ParserWorkingSet::new(None);
|
||||
|
||||
let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'));
|
||||
working_set.add_decl((b"foo").to_vec(), sig);
|
||||
|
||||
let (_, err) = working_set.parse_source(b"foo -j");
|
||||
assert!(matches!(err, Some(ParseError::MissingFlagParam(..))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn parse_call_too_many_shortflag_args() {
|
||||
let mut working_set = ParserWorkingSet::new(None);
|
||||
|
||||
let sig = Signature::build("foo")
|
||||
.named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'))
|
||||
.named("--math", SyntaxShape::Int, "math!!", Some('m'));
|
||||
working_set.add_decl((b"foo").to_vec(), sig);
|
||||
let (_, err) = working_set.parse_source(b"foo -mj");
|
||||
assert!(matches!(
|
||||
err,
|
||||
Some(ParseError::ShortFlagBatchCantTakeArg(..))
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn parse_call_unknown_shorthand() {
|
||||
let mut working_set = ParserWorkingSet::new(None);
|
||||
|
||||
let sig = Signature::build("foo").switch("--jazz", "jazz!!", Some('j'));
|
||||
working_set.add_decl((b"foo").to_vec(), sig);
|
||||
let (_, err) = working_set.parse_source(b"foo -mj");
|
||||
assert!(matches!(err, Some(ParseError::UnknownFlag(..))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn parse_call_extra_positional() {
|
||||
let mut working_set = ParserWorkingSet::new(None);
|
||||
|
||||
let sig = Signature::build("foo").switch("--jazz", "jazz!!", Some('j'));
|
||||
working_set.add_decl((b"foo").to_vec(), sig);
|
||||
let (_, err) = working_set.parse_source(b"foo -j 100");
|
||||
assert!(matches!(err, Some(ParseError::ExtraPositional(..))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn parse_call_missing_req_positional() {
|
||||
let mut working_set = ParserWorkingSet::new(None);
|
||||
|
||||
let sig = Signature::build("foo").required("jazz", SyntaxShape::Int, "jazz!!");
|
||||
working_set.add_decl((b"foo").to_vec(), sig);
|
||||
let (_, err) = working_set.parse_source(b"foo");
|
||||
assert!(matches!(err, Some(ParseError::MissingPositional(..))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn parse_call_missing_req_flag() {
|
||||
let mut working_set = ParserWorkingSet::new(None);
|
||||
|
||||
let sig =
|
||||
Signature::build("foo").required_named("--jazz", SyntaxShape::Int, "jazz!!", None);
|
||||
working_set.add_decl((b"foo").to_vec(), sig);
|
||||
let (_, err) = working_set.parse_source(b"foo");
|
||||
assert!(matches!(err, Some(ParseError::MissingRequiredFlag(..))));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue