Fixed tests and update object encoding functions to be functional without binding json-object-type as far as possible. ;; You can find a series of patches at https://github.com/yoichi/emacs/tree/fix/json-empty-object2 From d8549a88633704fc76eb6cdafa6b6ea591fb14e3 Mon Sep 17 00:00:00 2001 From: Yoichi Nakayama Date: Sun, 21 Aug 2016 23:54:43 +0900 Subject: [PATCH] Bind json-object-type on object encoding functions If elisp object are plist or hash-table, assume they are created with associated json-object-type. * json.el (json--plist-to-alist): Convert key format. (json-encode-hash-table, json-encode-alist, json-encode-plist): Bind json-object-type. * json-tests.el (test-json-plist-to-alist): Use default key type for expected value, and add test with json-key-type. (test-json-encode-key): Add test not to confuse internal symbols. (test-json-encode-hash-table, test-json-encode-alist-with-sort-predicate, test-json-encode-list): Use default key type. --- lisp/json.el | 134 ++++++++++++++++++++++++++---------------------- test/lisp/json-tests.el | 29 +++++++---- 2 files changed, 91 insertions(+), 72 deletions(-) diff --git a/lisp/json.el b/lisp/json.el index a387b08..24fefc5 100644 --- a/lisp/json.el +++ b/lisp/json.el @@ -174,6 +174,10 @@ Unlike `reverse', this keeps the property-value pairs intact." (while plist (let ((prop (pop plist)) (val (pop plist))) + (when (and (not json-key-type) + (keywordp prop)) + (setq prop (intern + (substring (symbol-name prop) 1)))) (push (cons prop val) res))) (nreverse res))) @@ -526,79 +530,85 @@ Please see the documentation of `json-object-type' and `json-key-type'." (defun json-encode-hash-table (hash-table) "Return a JSON representation of HASH-TABLE." - (if json-encoding-object-sort-predicate - (json-encode-alist (map-into hash-table 'list)) + (let ((json-object-type 'hash-table)) + (if json-encoding-object-sort-predicate + (let ((json-key-type + (or json-key-type + 'string))) + (json-encode-alist (map-into hash-table 'list))) + (format "{%s%s}" + (json-join + (let (r) + (json--with-indentation + (maphash + (lambda (k v) + (push (format + (if json-encoding-pretty-print + "%s%s: %s" + "%s%s:%s") + json--encoding-current-indentation + (json-encode-key k) + (json-encode v)) + r)) + hash-table)) + r) + json-encoding-separator) + (if (or (not json-encoding-pretty-print) + json-encoding-lisp-style-closings) + "" + json--encoding-current-indentation))))) + +;; List encoding (including alists and plists) + +(defun json-encode-alist (alist) + "Return a JSON representation of ALIST." + (let ((json-object-type 'alist)) + (when json-encoding-object-sort-predicate + (setq alist + (sort alist (lambda (a b) + (funcall json-encoding-object-sort-predicate + (car a) (car b)))))) (format "{%s%s}" (json-join - (let (r) - (json--with-indentation - (maphash - (lambda (k v) - (push (format - (if json-encoding-pretty-print - "%s%s: %s" - "%s%s:%s") - json--encoding-current-indentation - (json-encode-key k) - (json-encode v)) - r)) - hash-table)) - r) + (json--with-indentation + (mapcar (lambda (cons) + (format (if json-encoding-pretty-print + "%s%s: %s" + "%s%s:%s") + json--encoding-current-indentation + (json-encode-key (car cons)) + (json-encode (cdr cons)))) + alist)) json-encoding-separator) (if (or (not json-encoding-pretty-print) json-encoding-lisp-style-closings) "" json--encoding-current-indentation)))) -;; List encoding (including alists and plists) - -(defun json-encode-alist (alist) - "Return a JSON representation of ALIST." - (when json-encoding-object-sort-predicate - (setq alist - (sort alist (lambda (a b) - (funcall json-encoding-object-sort-predicate - (car a) (car b)))))) - (format "{%s%s}" - (json-join - (json--with-indentation - (mapcar (lambda (cons) - (format (if json-encoding-pretty-print - "%s%s: %s" - "%s%s:%s") - json--encoding-current-indentation - (json-encode-key (car cons)) - (json-encode (cdr cons)))) - alist)) - json-encoding-separator) - (if (or (not json-encoding-pretty-print) - json-encoding-lisp-style-closings) - "" - json--encoding-current-indentation))) - (defun json-encode-plist (plist) "Return a JSON representation of PLIST." - (if json-encoding-object-sort-predicate - (json-encode-alist (json--plist-to-alist plist)) - (let (result) - (json--with-indentation - (while plist - (push (concat - json--encoding-current-indentation - (json-encode-key (car plist)) - (if json-encoding-pretty-print - ": " - ":") - (json-encode (cadr plist))) - result) - (setq plist (cddr plist)))) - (concat "{" - (json-join (nreverse result) json-encoding-separator) - (if (and json-encoding-pretty-print - (not json-encoding-lisp-style-closings)) + (let ((json-object-type 'plist)) + (if json-encoding-object-sort-predicate + (json-encode-alist (json--plist-to-alist plist)) + (let (result) + (json--with-indentation + (while plist + (push (concat json--encoding-current-indentation - "") - "}")))) + (json-encode-key (car plist)) + (if json-encoding-pretty-print + ": " + ":") + (json-encode (cadr plist))) + result) + (setq plist (cddr plist)))) + (concat "{" + (json-join (nreverse result) json-encoding-separator) + (if (and json-encoding-pretty-print + (not json-encoding-lisp-style-closings)) + json--encoding-current-indentation + "") + "}"))))) (defun json-encode-list (list) "Return a JSON representation of LIST. diff --git a/test/lisp/json-tests.el b/test/lisp/json-tests.el index 78cebb4..d5abb58 100644 --- a/test/lisp/json-tests.el +++ b/test/lisp/json-tests.el @@ -62,9 +62,11 @@ Point is moved to beginning of the buffer." (ert-deftest test-json-plist-to-alist () (should (equal (json--plist-to-alist '()) '())) - (should (equal (json--plist-to-alist '(:a 1)) '((:a . 1)))) + (should (equal (json--plist-to-alist '(:a 1)) '((a . 1)))) + (let ((json-key-type 'keyword)) + (should (equal (json--plist-to-alist '(:a 1)) '((:a . 1))))) (should (equal (json--plist-to-alist '(:a 1 :b 2 :c 3)) - '((:a . 1) (:b . 2) (:c . 3))))) + '((a . 1) (b . 2) (c . 3))))) (ert-deftest test-json-advance () (json-tests--with-temp-buffer "{ \"a\": 1 }" @@ -177,9 +179,16 @@ Point is moved to beginning of the buffer." "\"\\nasdфыв\\u001f\u007ffgh\\t\""))) (ert-deftest test-json-encode-key () - (should (equal (json-encode-key "foo") "\"foo\"")) - (should (equal (json-encode-key 'foo) "\"foo\"")) - (should (equal (json-encode-key :foo) "\"foo\"")) + (let ((json-key-type 'string)) + (should (equal (json-encode-key "foo") "\"foo\"")) + (should-error (json-encode-key t) :type 'json-key-format)) + (let ((json-key-type 'symbol)) + (should (equal (json-encode-key 'foo) "\"foo\"")) + (should (equal (json-encode-key t) "\"t\"")) + (should (equal (json-encode-key :t) "\":t\""))) + (let ((json-key-type 'keyword)) + (should (equal (json-encode-key :foo) "\"foo\"")) + (should-error (json-encode-key t) :type 'json-key-format)) (should-error (json-encode-key 5) :type 'json-key-format) (should-error (json-encode-key ["foo"]) :type 'json-key-format) (should-error (json-encode-key '("foo")) :type 'json-key-format)) @@ -238,9 +247,9 @@ Point is moved to beginning of the buffer." (let ((hash-table (make-hash-table)) (json-encoding-object-sort-predicate 'string<) (json-encoding-pretty-print nil)) - (puthash :a 1 hash-table) - (puthash :b 2 hash-table) - (puthash :c 3 hash-table) + (puthash "a" 1 hash-table) + (puthash "b" 2 hash-table) + (puthash "c" 3 hash-table) (should (equal (json-encode hash-table) "{\"a\":1,\"b\":2,\"c\":3}")))) @@ -261,7 +270,7 @@ Point is moved to beginning of the buffer." (should (equal (json-encode plist) "{\"a\":1,\"b\":2,\"c\":3}")))) (ert-deftest test-json-encode-alist-with-sort-predicate () - (let ((alist '((:c . 3) (:a . 1) (:b . 2))) + (let ((alist '((c . 3) (a . 1) (b . 2))) (json-encoding-object-sort-predicate 'string<) (json-encoding-pretty-print nil)) (should (equal (json-encode alist) "{\"a\":1,\"b\":2,\"c\":3}")))) @@ -270,7 +279,7 @@ Point is moved to beginning of the buffer." (let ((json-encoding-pretty-print nil)) (should (equal (json-encode-list '(:a 1 :b 2)) "{\"a\":1,\"b\":2}")) - (should (equal (json-encode-list '((:a . 1) (:b . 2))) + (should (equal (json-encode-list '((a . 1) (b . 2))) "{\"a\":1,\"b\":2}")) (should (equal (json-encode-list '(1 2 3 4)) "[1,2,3,4]")))) -- 2.8.1 2016年8月21日(日) 22:32 Yoichi Nakayama : > The change in json-encode-key broke tests in json-tests.el. I'll > investigate it. > > Ran 34 tests, 28 results as expected, 6 unexpected (2016-08-21 > 22:30:23+0900) > > 6 unexpected results: > FAILED test-json-encode-alist-with-sort-predicate > FAILED test-json-encode-hash-table > FAILED test-json-encode-key > FAILED test-json-encode-list > FAILED test-json-encode-plist > FAILED test-json-encode-plist-with-sort-predicate > > -- > Yoichi NAKAYAMA >