diff --git a/src/builtins/strings.rs b/src/builtins/strings.rs index 611d0028..546a4a2b 100644 --- a/src/builtins/strings.rs +++ b/src/builtins/strings.rs @@ -146,11 +146,18 @@ fn split(span: &Span, params: &[Ref], args: &[Value], _strict: bool) -> Re let s = ensure_string(name, ¶ms[0], &args[0])?; let delimiter = ensure_string(name, ¶ms[1], &args[1])?; - Ok(Value::from_array( + // Handle https://github.com/microsoft/regorus/issues/291 + let parts: Vec = if delimiter.as_ref() == "" { + // If delimiter is "", str::split returns a leading and trailing "" whereas Golang's split doesn't. + // Therefore avoid str::split and instead return each char as a Value::String. + s.chars().map(|c| Value::from(c.to_string())).collect() + } else { s.split(delimiter.as_ref()) .map(|s| Value::String(s.into())) - .collect(), - )) + .collect() + }; + + Ok(Value::from(parts)) } fn to_string(v: &Value, unescape: bool) -> String { diff --git a/tests/interpreter/cases/builtins/strings/split.yaml b/tests/interpreter/cases/builtins/strings/split.yaml new file mode 100644 index 00000000..a71444a3 --- /dev/null +++ b/tests/interpreter/cases/builtins/strings/split.yaml @@ -0,0 +1,17 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +cases: + - note: empty separator + data: {} + modules: [] + query: "x := split(\"test\", \"\")" + want_result: + x: ["t", "e", "s", "t"] + + - note: empty separator, empty string + data: {} + modules: [] + query: "x := split(\"\", \"\")" + want_result: + x: []