From: Damien Cassou <damien@cassou.me>
To: Yoichi Nakayama <yoichi.nakayama@gmail.com>
Cc: Philipp Stephani <phst@google.com>,
Mark Oteiza <mvoteiza@udel.edu>,
Theresa O'Connor <ted@oconnor.cx>,
24252@debbugs.gnu.org, Dmitry Gutov <dgutov@yandex.ru>
Subject: bug#24252: 25.1; json.el doesn't distinguish null and empty object
Date: Sat, 19 May 2018 08:52:42 +0200 [thread overview]
Message-ID: <87o9hci1c5.fsf@cassou.me> (raw)
In-Reply-To: <m2eg5nwinp.fsf@gizaemon.local.i-did-not-set--mail-host-address--so-tickle-me> (Yoichi Nakayama's message of "Wed, 17 Aug 2016 23:54:02 +0900")
[-- Attachment #1: Type: text/plain, Size: 499 bytes --]
Yoichi Nakayama <yoichi.nakayama@gmail.com> writes:
> When json-pretty-print applied to "{}", it is
> unexpectedly converted to "null".
> This is caused by internal representations of null
> and empty object are the same:
> (json-read-from-string "{}") ; => nil
> (json-read-from-string "null") ; => nil
please find a patch attached. This patch uses :json-null to distinguish,
during pretty-print, between the value null and an empty object.
All tests pass and many new tests are added.
Best
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Fix-pretty-printing-empty-objects-as-null.patch --]
[-- Type: text/x-patch, Size: 4751 bytes --]
From 78eb7b659809444f7c9690db73e1f65843d5658c Mon Sep 17 00:00:00 2001
From: Damien Cassou <damien@cassou.me>
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 d374f452e6..cd95ec2832 100644
--- a/lisp/json.el
+++ b/lisp/json.el
@@ -609,8 +609,7 @@ json-encode-list
"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 @@ json-encode
((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 @@ json-pretty-print
(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 ea562e8b13..84039c09ce 100644
--- a/test/lisp/json-tests.el
+++ b/test/lisp/json-tests.el
@@ -325,5 +325,72 @@ json-tests--with-temp-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.17.0
[-- Attachment #3: Type: text/plain, Size: 164 bytes --]
--
Damien Cassou
http://damiencassou.seasidehosting.st
"Success is the ability to go from one failure to another without
losing enthusiasm." --Winston Churchill
next prev parent reply other threads:[~2018-05-19 6:52 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-08-17 14:54 bug#24252: 25.1; json.el doesn't distinguish null and empty object Yoichi Nakayama
2016-08-19 2:06 ` Dmitry Gutov
2016-08-19 23:45 ` Yoichi Nakayama
2016-08-20 0:52 ` Dmitry Gutov
2016-08-20 6:12 ` Yoichi Nakayama
2016-08-21 1:30 ` Yoichi Nakayama
2016-08-21 3:42 ` Dmitry Gutov
2016-08-21 12:11 ` Yoichi Nakayama
2016-08-21 13:32 ` Yoichi Nakayama
2016-08-21 15:06 ` Yoichi Nakayama
2016-08-27 0:05 ` Dmitry Gutov
2018-05-17 14:39 ` Damien Cassou
2018-05-19 6:52 ` Damien Cassou [this message]
2018-05-28 15:21 ` Nicolas Petton
2018-06-11 13:36 ` Damien Cassou
2018-06-12 17:14 ` Eli Zaretskii
2018-06-13 7:13 ` Damien Cassou
2018-06-13 13:05 ` Nicolas Petton
2018-06-13 16:55 ` Eli Zaretskii
2018-06-14 9:04 ` Nicolas Petton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87o9hci1c5.fsf@cassou.me \
--to=damien@cassou.me \
--cc=24252@debbugs.gnu.org \
--cc=dgutov@yandex.ru \
--cc=mvoteiza@udel.edu \
--cc=phst@google.com \
--cc=ted@oconnor.cx \
--cc=yoichi.nakayama@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).