forked from extern/nushell
Command tests (#922)
* WIP command tests * Finish marking todo tests * update * update * Windows cd test ignoring
This commit is contained in:
@ -426,7 +426,7 @@ fn display(help: &str, engine_state: &EngineState, stack: &mut Stack, span: Span
|
||||
if let Ok(output) = decl.run(
|
||||
engine_state,
|
||||
stack,
|
||||
&Call::new(),
|
||||
&Call::new(span),
|
||||
Value::String {
|
||||
val: item.to_string(),
|
||||
span: Span { start: 0, end: 0 },
|
||||
|
@ -142,7 +142,7 @@ impl Command for Open {
|
||||
Some(converter_id) => engine_state.get_decl(converter_id).run(
|
||||
engine_state,
|
||||
stack,
|
||||
&Call::new(),
|
||||
&Call::new(call_span),
|
||||
output,
|
||||
),
|
||||
None => Ok(output),
|
||||
|
@ -71,7 +71,7 @@ impl Command for Save {
|
||||
let output = engine_state.get_decl(converter_id).run(
|
||||
engine_state,
|
||||
stack,
|
||||
&Call::new(),
|
||||
&Call::new(span),
|
||||
input,
|
||||
)?;
|
||||
|
||||
|
@ -82,6 +82,10 @@ fn getcol(
|
||||
.map(move |x| Value::String { val: x, span })
|
||||
.into_pipeline_data(engine_state.ctrlc.clone()))
|
||||
}
|
||||
PipelineData::Value(Value::Record { cols, .. }, ..) => Ok(cols
|
||||
.into_iter()
|
||||
.map(move |x| Value::String { val: x, span })
|
||||
.into_pipeline_data(engine_state.ctrlc.clone())),
|
||||
PipelineData::Value(..) | PipelineData::RawStream(..) => {
|
||||
let cols = vec![];
|
||||
let vals = vec![];
|
||||
|
@ -30,7 +30,7 @@ impl Command for Lines {
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let head = call.head;
|
||||
let skip_empty = call.has_flag("skip-emtpy");
|
||||
let skip_empty = call.has_flag("skip-empty");
|
||||
match input {
|
||||
#[allow(clippy::needless_collect)]
|
||||
// Collect is needed because the string may not live long enough for
|
||||
@ -39,13 +39,21 @@ impl Command for Lines {
|
||||
PipelineData::Value(Value::String { val, span }, ..) => {
|
||||
let split_char = if val.contains("\r\n") { "\r\n" } else { "\n" };
|
||||
|
||||
let lines = val
|
||||
let mut lines = val
|
||||
.split(split_char)
|
||||
.map(|s| s.to_string())
|
||||
.collect::<Vec<String>>();
|
||||
|
||||
// if the last one is empty, remove it, as it was just
|
||||
// a newline at the end of the input we got
|
||||
if let Some(last) = lines.last() {
|
||||
if last.is_empty() {
|
||||
lines.pop();
|
||||
}
|
||||
}
|
||||
|
||||
let iter = lines.into_iter().filter_map(move |s| {
|
||||
if skip_empty && s.is_empty() {
|
||||
if skip_empty && s.trim().is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(Value::string(s, span))
|
||||
@ -65,21 +73,30 @@ impl Command for Lines {
|
||||
split_char = "\r\n";
|
||||
}
|
||||
|
||||
let inner = val
|
||||
let mut lines = val
|
||||
.split(split_char)
|
||||
.filter_map(|s| {
|
||||
if skip_empty && s.is_empty() {
|
||||
if skip_empty && s.trim().is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(Value::String {
|
||||
val: s.into(),
|
||||
span,
|
||||
})
|
||||
Some(s.to_string())
|
||||
}
|
||||
})
|
||||
.collect::<Vec<Value>>();
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
Some(inner)
|
||||
// if the last one is empty, remove it, as it was just
|
||||
// a newline at the end of the input we got
|
||||
if let Some(last) = lines.last() {
|
||||
if last.is_empty() {
|
||||
lines.pop();
|
||||
}
|
||||
}
|
||||
|
||||
Some(
|
||||
lines
|
||||
.into_iter()
|
||||
.map(move |x| Value::String { val: x, span }),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -102,13 +119,21 @@ impl Command for Lines {
|
||||
let split_char = if s.contains("\r\n") { "\r\n" } else { "\n" };
|
||||
|
||||
#[allow(clippy::needless_collect)]
|
||||
let lines = s
|
||||
let mut lines = s
|
||||
.split(split_char)
|
||||
.map(|s| s.to_string())
|
||||
.collect::<Vec<String>>();
|
||||
|
||||
// if the last one is empty, remove it, as it was just
|
||||
// a newline at the end of the input we got
|
||||
if let Some(last) = lines.last() {
|
||||
if last.is_empty() {
|
||||
lines.pop();
|
||||
}
|
||||
}
|
||||
|
||||
let iter = lines.into_iter().filter_map(move |s| {
|
||||
if skip_empty && s.is_empty() {
|
||||
if skip_empty && s.trim().is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(Value::string(s, head))
|
||||
|
@ -94,6 +94,13 @@ END:VCALENDAR' | from ics",
|
||||
|
||||
fn from_ics(input: PipelineData, head: Span, config: &Config) -> Result<PipelineData, ShellError> {
|
||||
let input_string = input.collect_string("", config)?;
|
||||
|
||||
let input_string = input_string
|
||||
.lines()
|
||||
.map(|x| x.trim().to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
let input_bytes = input_string.as_bytes();
|
||||
let buf_reader = BufReader::new(input_bytes);
|
||||
let parser = ical::IcalParser::new(buf_reader);
|
||||
@ -103,9 +110,9 @@ fn from_ics(input: PipelineData, head: Span, config: &Config) -> Result<Pipeline
|
||||
for calendar in parser {
|
||||
match calendar {
|
||||
Ok(c) => output.push(calendar_to_value(c, head)),
|
||||
Err(_) => output.push(Value::Error {
|
||||
Err(e) => output.push(Value::Error {
|
||||
error: ShellError::UnsupportedInput(
|
||||
"input cannot be parsed as .ics".to_string(),
|
||||
format!("input cannot be parsed as .ics ({})", e),
|
||||
head,
|
||||
),
|
||||
}),
|
||||
|
@ -125,14 +125,24 @@ END:VCARD' | from vcf",
|
||||
|
||||
fn from_vcf(input: PipelineData, head: Span, config: &Config) -> Result<PipelineData, ShellError> {
|
||||
let input_string = input.collect_string("", config)?;
|
||||
|
||||
let input_string = input_string
|
||||
.lines()
|
||||
.map(|x| x.trim().to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
let input_bytes = input_string.as_bytes();
|
||||
let cursor = std::io::Cursor::new(input_bytes);
|
||||
let parser = ical::VcardParser::new(cursor);
|
||||
|
||||
let iter = parser.map(move |contact| match contact {
|
||||
Ok(c) => contact_to_value(c, head),
|
||||
Err(_) => Value::Error {
|
||||
error: ShellError::UnsupportedInput("input cannot be parsed as .vcf".to_string(), head),
|
||||
Err(e) => Value::Error {
|
||||
error: ShellError::UnsupportedInput(
|
||||
format!("input cannot be parsed as .vcf ({})", e),
|
||||
head,
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -265,7 +265,7 @@ fn helper(
|
||||
Some(converter_id) => engine_state.get_decl(converter_id).run(
|
||||
engine_state,
|
||||
stack,
|
||||
&Call::new(),
|
||||
&Call::new(span),
|
||||
output,
|
||||
),
|
||||
None => Ok(output),
|
||||
|
@ -2,14 +2,14 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::{Call, CellPath},
|
||||
engine::{Command, EngineState, Stack},
|
||||
Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SubCommand;
|
||||
|
||||
struct Arguments {
|
||||
character: Option<Value>,
|
||||
character: Option<Spanned<String>>,
|
||||
column_paths: Vec<CellPath>,
|
||||
}
|
||||
|
||||
@ -143,7 +143,16 @@ where
|
||||
input,
|
||||
);
|
||||
let to_trim = match options.character.as_ref() {
|
||||
Some(v) => v.as_string()?.chars().next(),
|
||||
Some(v) => {
|
||||
if v.item.chars().count() > 1 {
|
||||
return Err(ShellError::SpannedLabeledError(
|
||||
"Trim only works with single character".into(),
|
||||
"needs single character".into(),
|
||||
v.span,
|
||||
));
|
||||
}
|
||||
v.item.chars().next()
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
|
||||
|
@ -220,7 +220,7 @@ impl ExternalCommand {
|
||||
&crate::Table,
|
||||
&engine_state,
|
||||
&mut stack,
|
||||
&Call::new(),
|
||||
&Call::new(head),
|
||||
input,
|
||||
);
|
||||
|
||||
|
Reference in New Issue
Block a user