Skip to content

Commit c7bb77b

Browse files
committed
Fix remarks
1 parent d1293b4 commit c7bb77b

File tree

2 files changed

+59
-19
lines changed

2 files changed

+59
-19
lines changed

dsc/tests/dsc_functions.tests.ps1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ Describe 'tests for function expressions' {
412412
It 'join function works for: <expression>' -TestCases @(
413413
@{ expression = "[join(createArray('a','b','c'), '-')]"; expected = 'a-b-c' }
414414
@{ expression = "[join(createArray(), '-')]"; expected = '' }
415+
@{ expression = "[join(createArray(1,2,3), ',')]"; expected = '1,2,3' }
415416
) {
416417
param($expression, $expected)
417418

dsc_lib/src/functions/join.rs

Lines changed: 58 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ use tracing::debug;
1111
#[derive(Debug, Default)]
1212
pub struct Join {}
1313

14-
fn stringify_value(v: &Value) -> String {
14+
fn stringify_value(v: &Value) -> Result<String, DscError> {
1515
match v {
16-
Value::String(s) => s.clone(),
17-
Value::Number(n) => n.to_string(),
18-
Value::Bool(b) => b.to_string(),
19-
Value::Null => "null".to_string(),
20-
// Fallback to JSON for arrays/objects
21-
_ => serde_json::to_string(v).unwrap_or_default(),
16+
Value::String(s) => Ok(s.clone()),
17+
Value::Number(n) => Ok(n.to_string()),
18+
Value::Bool(b) => Ok(b.to_string()),
19+
Value::Null => Err(DscError::Parser("Array elements cannot be null".to_string())),
20+
Value::Array(_) => Err(DscError::Parser("Array elements cannot be arrays".to_string())),
21+
Value::Object(_) => Err(DscError::Parser("Array elements cannot be objects".to_string())),
2222
}
2323
}
2424

@@ -32,15 +32,7 @@ impl Function for Join {
3232
max_args: 2,
3333
accepted_arg_ordered_types: vec![
3434
vec![FunctionArgKind::Array],
35-
// delimiter: accept any type (no validation), convert to string
36-
vec![
37-
FunctionArgKind::Array,
38-
FunctionArgKind::Boolean,
39-
FunctionArgKind::Null,
40-
FunctionArgKind::Number,
41-
FunctionArgKind::Object,
42-
FunctionArgKind::String,
43-
],
35+
vec![FunctionArgKind::String],
4436
],
4537
remaining_arg_accepted_types: None,
4638
return_types: vec![FunctionArgKind::String],
@@ -50,11 +42,12 @@ impl Function for Join {
5042
fn invoke(&self, args: &[Value], _context: &Context) -> Result<Value, DscError> {
5143
debug!("{}", t!("functions.join.invoked"));
5244

53-
let delimiter = stringify_value(&args[1]);
45+
let delimiter = args[1].as_str().unwrap();
5446

5547
if let Some(array) = args[0].as_array() {
56-
let items: Vec<String> = array.iter().map(stringify_value).collect();
57-
return Ok(Value::String(items.join(&delimiter)));
48+
let items: Result<Vec<String>, DscError> = array.iter().map(stringify_value).collect();
49+
let items = items?;
50+
return Ok(Value::String(items.join(delimiter)));
5851
}
5952

6053
Err(DscError::Parser(t!("functions.join.invalidArrayArg").to_string()))
@@ -65,6 +58,8 @@ impl Function for Join {
6558
mod tests {
6659
use crate::configure::context::Context;
6760
use crate::parser::Statement;
61+
use super::Join;
62+
use crate::functions::Function;
6863

6964
#[test]
7065
fn join_array_of_strings() {
@@ -86,4 +81,48 @@ mod tests {
8681
let result = parser.parse_and_execute("[join(createArray(1,2,3), ',')]", &Context::new()).unwrap();
8782
assert_eq!(result, "1,2,3");
8883
}
84+
85+
#[test]
86+
fn join_array_with_null_fails() {
87+
let mut parser = Statement::new().unwrap();
88+
let result = parser.parse_and_execute("[join(createArray('a', null()), ',')]", &Context::new());
89+
assert!(result.is_err());
90+
// The error comes from argument validation, not our function
91+
assert!(result.unwrap_err().to_string().contains("does not accept null arguments"));
92+
}
93+
94+
#[test]
95+
fn join_array_with_array_fails() {
96+
let mut parser = Statement::new().unwrap();
97+
let result = parser.parse_and_execute("[join(createArray('a', createArray('b')), ',')]", &Context::new());
98+
assert!(result.is_err());
99+
let error_msg = result.unwrap_err().to_string();
100+
assert!(error_msg.contains("Arguments must all be arrays") || error_msg.contains("mixed types"));
101+
}
102+
103+
#[test]
104+
fn join_array_with_object_fails() {
105+
let mut parser = Statement::new().unwrap();
106+
let result = parser.parse_and_execute("[join(createArray('a', createObject('key', 'value')), ',')]", &Context::new());
107+
assert!(result.is_err());
108+
let error_msg = result.unwrap_err().to_string();
109+
assert!(error_msg.contains("Arguments must all be") || error_msg.contains("mixed types"));
110+
}
111+
112+
#[test]
113+
fn join_direct_test_with_mixed_array() {
114+
use serde_json::json;
115+
use crate::configure::context::Context;
116+
117+
let join_fn = Join::default();
118+
let args = vec![
119+
json!(["hello", {"key": "value"}]), // Array with string and object
120+
json!(",")
121+
];
122+
let result = join_fn.invoke(&args, &Context::new());
123+
124+
assert!(result.is_err());
125+
let error_msg = result.unwrap_err().to_string();
126+
assert!(error_msg.contains("Array elements cannot be objects"));
127+
}
89128
}

0 commit comments

Comments
 (0)