Repository: google/jsonnet (language: python)

Issue:
Strings not escaped in assertEqual errors
Code:
```
std.assertEqual("\n ", "\n")
```

Expected output:
```
RUNTIME ERROR: Assertion failed. "\n " != "\n"
        std.jsonnet:649:13-91   function <anonymous>
        testdata/assert_equal5.input:1:1-28
```

Actual output:
```
RUNTIME ERROR: Assertion failed. 
  != 

        std.jsonnet:649:13-55   function <anonymous>
        testdata/assert_equal5.input:1:1-28
```

Another example where it is pretty important:
```
std.assertEqual("\u001b[31m", "")
```



Discussion / hints:

Fix patch:
diff --git a/stdlib/std.jsonnet b/stdlib/std.jsonnet
index 0e4908b5e..b2780cd54 100644
--- a/stdlib/std.jsonnet
+++ b/stdlib/std.jsonnet
@@ -831,10 +831,14 @@ limitations under the License.
       std.map(map_func, std.filter(filter_func, arr)),
 
   assertEqual(a, b)::
+    // If the values are strings, escape them for printing.
+    // If not, they'll be JSON-stringified anyway by the later string concatenation.
+    local astr = if std.type(a) == 'string' then std.escapeStringJson(a) else a;
+    local bstr = if std.type(b) == 'string' then std.escapeStringJson(b) else b;
     if a == b then
       true
     else
-      error 'Assertion failed. ' + a + ' != ' + b,
+      error 'Assertion failed. ' + astr + ' != ' + bstr,
 
   abs(n)::
     if !std.isNumber(n) then


Test patch:
diff --git a/test_suite/error.assert_equal_obj.jsonnet b/test_suite/error.assert_equal_obj.jsonnet
new file mode 100644
index 000000000..2dfa928f6
--- /dev/null
+++ b/test_suite/error.assert_equal_obj.jsonnet
@@ -0,0 +1,17 @@
+/*
+Copyright 2024 Google Inc. All rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+std.assertEqual({ a: 1 }, { b: 1 })
diff --git a/test_suite/error.assert_equal_obj.jsonnet.golden b/test_suite/error.assert_equal_obj.jsonnet.golden
new file mode 100644
index 000000000..093ced7c1
--- /dev/null
+++ b/test_suite/error.assert_equal_obj.jsonnet.golden
@@ -0,0 +1,3 @@
+RUNTIME ERROR: Assertion failed. {"a": 1} != {"b": 1}
+	std.jsonnet:<stdlib_position_redacted>	function <anonymous>
+	error.assert_equal_obj.jsonnet:17:1-36	
diff --git a/test_suite/error.assert_equal_str.jsonnet b/test_suite/error.assert_equal_str.jsonnet
new file mode 100644
index 000000000..77c3ad3a7
--- /dev/null
+++ b/test_suite/error.assert_equal_str.jsonnet
@@ -0,0 +1,17 @@
+/*
+Copyright 2024 Google Inc. All rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+std.assertEqual('one\ntwo', 'three\nfour\n')
diff --git a/test_suite/error.assert_equal_str.jsonnet.golden b/test_suite/error.assert_equal_str.jsonnet.golden
new file mode 100644
index 000000000..d654b3e3f
--- /dev/null
+++ b/test_suite/error.assert_equal_str.jsonnet.golden
@@ -0,0 +1,3 @@
+RUNTIME ERROR: Assertion failed. "one\ntwo" != "three\nfour\n"
+	std.jsonnet:<stdlib_position_redacted>	function <anonymous>
+	error.assert_equal_str.jsonnet:17:1-45