diff --git a/sjsonnet/src/sjsonnet/stdlib/ManifestModule.scala b/sjsonnet/src/sjsonnet/stdlib/ManifestModule.scala index b7591e8a..6b25918f 100644 --- a/sjsonnet/src/sjsonnet/stdlib/ManifestModule.scala +++ b/sjsonnet/src/sjsonnet/stdlib/ManifestModule.scala @@ -347,25 +347,14 @@ object ManifestModule extends AbstractFunctionModule { */ private object Lines extends Val.Builtin1("lines", "arr") { def evalRhs(v1: Eval, ev: EvalScope, pos: Position): Val = { + val out = new StringBuilder v1.value.asArr.foreach { - case _: Val.Str | _: Val.Null => // donothing - case x => + case s: Val.Str => out.append(s.str).append('\n') + case _: Val.Null => // skip nulls like std.join + case x => Error.fail("std.lines: expected string or null element, got " + x.value.prettyName) } - Val.Str( - pos, - Materializer - .apply(v1.value)(ev) - .asInstanceOf[ujson.Arr] - .value - .filter(_ != ujson.Null) - .map { - case ujson.Str(s) => s + "\n" - case _ => - throw new RuntimeException("Unexpected") /* we ensure it's all strings above */ - } - .mkString - ) + Val.Str(pos, out.toString) } } diff --git a/sjsonnet/test/resources/new_test_suite/error.std_lines_string.jsonnet b/sjsonnet/test/resources/new_test_suite/error.std_lines_string.jsonnet new file mode 100644 index 00000000..5ca2e7d7 --- /dev/null +++ b/sjsonnet/test/resources/new_test_suite/error.std_lines_string.jsonnet @@ -0,0 +1 @@ +std.lines("a\nb\n") diff --git a/sjsonnet/test/resources/new_test_suite/error.std_lines_string.jsonnet.golden b/sjsonnet/test/resources/new_test_suite/error.std_lines_string.jsonnet.golden new file mode 100644 index 00000000..7a4159ae --- /dev/null +++ b/sjsonnet/test/resources/new_test_suite/error.std_lines_string.jsonnet.golden @@ -0,0 +1,2 @@ +sjsonnet.Error: [std.lines] Wrong parameter type: expected Array, got string + at [].(error.std_lines_string.jsonnet:1:10) diff --git a/sjsonnet/test/src/sjsonnet/StdLibOfficialCompatibilityTests.scala b/sjsonnet/test/src/sjsonnet/StdLibOfficialCompatibilityTests.scala index 6c51814a..6053e0a3 100644 --- a/sjsonnet/test/src/sjsonnet/StdLibOfficialCompatibilityTests.scala +++ b/sjsonnet/test/src/sjsonnet/StdLibOfficialCompatibilityTests.scala @@ -15,6 +15,15 @@ object StdLibOfficialCompatibilityTests extends TestSuite { assert(evalErr("""std.flattenArrays([[1], null, [2]])""").contains("array and null")) } + test("lines follows official array-to-text semantics") { + eval("""std.lines(["a", "b"])""") ==> ujson.Str("a\nb\n") + eval("""std.lines(["a", null, "b"])""") ==> ujson.Str("a\nb\n") + + val stringInputError = evalErr("""std.lines("a\nb\n")""") + assert(stringInputError.contains("expected Array")) + assert(stringInputError.contains("got string")) + } + test("flattenDeepArray wraps scalar values") { eval("""std.flattenDeepArray(1)""") ==> ujson.Arr(1) eval("""std.flattenDeepArray(null)""") ==> ujson.Arr(ujson.Null)