From 8cb9beb32163fa3ce3b052ced646fd673814ddc6 Mon Sep 17 00:00:00 2001 From: Damien Cassou Date: Sat, 19 May 2018 08:36:32 +0200 Subject: [PATCH] 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. --- lisp/json.el | 7 +++-- test/lisp/json-tests.el | 67 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/lisp/json.el b/lisp/json.el index d374f452e6b..cd95ec28327 100644 --- a/lisp/json.el +++ b/lisp/json.el @@ -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))) diff --git a/test/lisp/json-tests.el b/test/lisp/json-tests.el index ea562e8b134..84039c09cee 100644 --- a/test/lisp/json-tests.el +++ b/test/lisp/json-tests.el @@ -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 -- 2.39.2