1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-12-28 10:56:36 +00:00

Fix pretty-printing empty objects as null

* lisp/json.el (json-pretty-print): Force distinction between empty
  objects and null.
(json-encode-list): Remove responsibility to print "null" as this
value is not a list.
(json-encode): Give higher precedence to lists so that an empty list
is printed as an empty object, not as "null".

* test/lisp/json-tests.el (test-json-encode): Add many tests to check
  the behavior of pretty-printing.
This commit is contained in:
Damien Cassou 2018-05-19 08:36:32 +02:00 committed by Nicolas Petton
parent 967d2c55ef
commit 8cb9beb321
No known key found for this signature in database
GPG Key ID: E8BCD7866AFCF978
2 changed files with 71 additions and 3 deletions

View File

@ -609,8 +609,7 @@ Please see the documentation of `json-object-type' and `json-key-type'."
"Return a JSON representation of LIST.
Tries to DWIM: simple lists become JSON arrays, while alists and plists
become JSON objects."
(cond ((null list) "null")
((json-alist-p list) (json-encode-alist list))
(cond ((json-alist-p list) (json-encode-alist list))
((json-plist-p list) (json-encode-plist list))
((listp list) (json-encode-array list))
(t
@ -723,12 +722,12 @@ Advances point just past JSON object."
((stringp object) (json-encode-string object))
((keywordp object) (json-encode-string
(substring (symbol-name object) 1)))
((listp object) (json-encode-list object))
((symbolp object) (json-encode-string
(symbol-name object)))
((numberp object) (json-encode-number object))
((arrayp object) (json-encode-array object))
((hash-table-p object) (json-encode-hash-table object))
((listp object) (json-encode-list object))
(t (signal 'json-error (list object)))))
;; Pretty printing
@ -743,6 +742,8 @@ Advances point just past JSON object."
(interactive "r")
(atomic-change-group
(let ((json-encoding-pretty-print t)
;; Distinguish an empty objects from 'null'
(json-null :json-null)
;; Ensure that ordering is maintained
(json-object-type 'alist)
(txt (delete-and-extract-region begin end)))

View File

@ -325,5 +325,72 @@ Point is moved to beginning of the buffer."
(with-temp-buffer
(should-error (json-encode (current-buffer)) :type 'json-error)))
;;; Pretty-print
(defun json-tests-equal-pretty-print (original &optional expected)
"Abort current test if pretty-printing ORIGINAL does not yield EXPECTED.
Both ORIGINAL and EXPECTED should be strings. If EXPECTED is
nil, ORIGINAL should stay unchanged by pretty-printing."
(with-temp-buffer
(insert original)
(json-pretty-print-buffer)
(should (equal (buffer-string) (or expected original)))))
(ert-deftest test-json-pretty-print-string ()
(json-tests-equal-pretty-print "\"\"")
(json-tests-equal-pretty-print "\"foo\""))
(ert-deftest test-json-pretty-print-atom ()
(json-tests-equal-pretty-print "true")
(json-tests-equal-pretty-print "false")
(json-tests-equal-pretty-print "null"))
(ert-deftest test-json-pretty-print-number ()
(json-tests-equal-pretty-print "123")
(json-tests-equal-pretty-print "0.123"))
(ert-deftest test-json-pretty-print-object ()
;; empty (regression test for bug#24252)
(json-tests-equal-pretty-print
"{}"
"{\n}")
;; one pair
(json-tests-equal-pretty-print
"{\"key\":1}"
"{\n \"key\": 1\n}")
;; two pairs
(json-tests-equal-pretty-print
"{\"key1\":1,\"key2\":2}"
"{\n \"key1\": 1,\n \"key2\": 2\n}")
;; embedded object
(json-tests-equal-pretty-print
"{\"foo\":{\"key\":1}}"
"{\n \"foo\": {\n \"key\": 1\n }\n}")
;; embedded array
(json-tests-equal-pretty-print
"{\"key\":[1,2]}"
"{\n \"key\": [\n 1,\n 2\n ]\n}"))
(ert-deftest test-json-pretty-print-array ()
;; empty
(json-tests-equal-pretty-print "[]")
;; one item
(json-tests-equal-pretty-print
"[1]"
"[\n 1\n]")
;; two items
(json-tests-equal-pretty-print
"[1,2]"
"[\n 1,\n 2\n]")
;; embedded object
(json-tests-equal-pretty-print
"[{\"key\":1}]"
"[\n {\n \"key\": 1\n }\n]")
;; embedded array
(json-tests-equal-pretty-print
"[[1,2]]"
"[\n [\n 1,\n 2\n ]\n]"))
(provide 'json-tests)
;;; json-tests.el ends here