Type validation for headers command (#6918) (#7047)

cargo clippy lints

tests

format

Co-authored-by: Ricardo Monteiro <ricardo.monteiro@getmanta.com>
This commit is contained in:
raccmonteiro 2022-11-10 00:43:24 +00:00 committed by GitHub
parent c4cb3a77cb
commit 7b0c0692dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 117 additions and 11 deletions

View File

@ -122,20 +122,42 @@ fn replace_headers(value: Value, headers: &[String]) -> Result<Value, ShellError
}
}
fn is_valid_header(value: &Value) -> bool {
matches!(
value,
Value::Nothing { span: _ }
| Value::String { val: _, span: _ }
| Value::Bool { val: _, span: _ }
| Value::Float { val: _, span: _ }
| Value::Int { val: _, span: _ }
)
}
fn extract_headers(value: &Value, config: &Config) -> Result<Vec<String>, ShellError> {
match value {
Value::Record { vals, .. } => Ok(vals
.iter()
.enumerate()
.map(|(idx, value)| {
let col = value.into_string("", config);
if col.is_empty() {
format!("column{}", idx)
} else {
col
Value::Record { vals, .. } => {
for v in vals {
if !is_valid_header(v) {
return Err(ShellError::TypeMismatch(
"compatible type: Null, String, Bool, Float, Int".to_string(),
v.span()?,
));
}
})
.collect::<Vec<String>>()),
}
Ok(vals
.iter()
.enumerate()
.map(|(idx, value)| {
let col = value.into_string("", config);
if col.is_empty() {
format!("column{}", idx)
} else {
col
}
})
.collect::<Vec<String>>())
}
Value::List { vals, span } => vals
.iter()
.map(|value| extract_headers(value, config))

View File

@ -29,3 +29,87 @@ fn headers_adds_missing_column_name() {
assert_eq!(actual.out, r#"["r1c1","r2c1"]"#)
}
#[test]
fn headers_invalid_column_type_empty_record() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
[[a b]; [{}, 2], [3,4] ]
| headers"#
));
assert!(actual
.err
.contains("needs compatible type: Null, String, Bool, Float, Int"));
}
#[test]
fn headers_invalid_column_type_record() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
[[a b]; [1 ($nu.scope)] [2 2]]
| headers"#
));
assert!(actual
.err
.contains("needs compatible type: Null, String, Bool, Float, Int"));
}
#[test]
fn headers_invalid_column_type_array() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
[[a b]; [[f,g], 2], [3,4] ]
| headers"#
));
assert!(actual
.err
.contains("needs compatible type: Null, String, Bool, Float, Int"));
}
#[test]
fn headers_invalid_column_type_range() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
[[a b]; [(1..5), 2], [3,4] ]
| headers"#
));
assert!(actual
.err
.contains("needs compatible type: Null, String, Bool, Float, Int"));
}
#[test]
fn headers_invalid_column_type_duration() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
[[a b]; [((date now) - (date now)), 2], [3,4] ]
| headers"#
));
assert!(actual
.err
.contains("needs compatible type: Null, String, Bool, Float, Int"));
}
#[test]
fn headers_invalid_column_type_binary() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
[[a b]; [("aa" | into binary), 2], [3,4] ]
| headers"#
));
assert!(actual
.err
.contains("needs compatible type: Null, String, Bool, Float, Int"));
}