summaryrefslogtreecommitdiff
path: root/tests/test-prog-json--json-format-buffer.el
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-03-02 19:46:38 -0600
committerCraig Jennings <c@cjennings.net>2026-03-02 19:46:38 -0600
commitb5cae72d8f824f235f351821f7d7052b66bc2513 (patch)
tree264261c26ec5a6c721e5dbd83e93237e842e53b5 /tests/test-prog-json--json-format-buffer.el
parenta46f8af939b112b603a2c95b2e83a1932b208e20 (diff)
feat(json,yaml): add tree-sitter modes, formatting, and jq integration
New prog-json module: json-ts-mode with jq formatting (C-; f) and jq-interactively (C-c C-q). Upgraded prog-yaml to yaml-ts-mode with prettier formatting. Both use treesit-auto for grammar management. Includes 18 new tests (10 JSON, 8 YAML), 185/185 passing.
Diffstat (limited to 'tests/test-prog-json--json-format-buffer.el')
-rw-r--r--tests/test-prog-json--json-format-buffer.el109
1 files changed, 109 insertions, 0 deletions
diff --git a/tests/test-prog-json--json-format-buffer.el b/tests/test-prog-json--json-format-buffer.el
new file mode 100644
index 00000000..227eafb9
--- /dev/null
+++ b/tests/test-prog-json--json-format-buffer.el
@@ -0,0 +1,109 @@
+;;; test-prog-json--json-format-buffer.el --- Tests for cj/json-format-buffer -*- lexical-binding: t -*-
+
+;;; Commentary:
+;; Tests for the cj/json-format-buffer function in prog-json.el.
+;; Tests both the jq path and the built-in fallback path.
+
+;;; Code:
+
+(require 'ert)
+(require 'json)
+(require 'prog-json)
+
+;;; Normal Cases — jq path
+
+(ert-deftest test-prog-json--json-format-buffer-normal-formats-object ()
+ "Compact JSON object is pretty-printed with sorted keys."
+ (with-temp-buffer
+ (insert "{\"zebra\":1,\"alpha\":2}")
+ (cj/json-format-buffer)
+ (should (string= (string-trim (buffer-string))
+ "{\n \"alpha\": 2,\n \"zebra\": 1\n}"))))
+
+(ert-deftest test-prog-json--json-format-buffer-normal-formats-array ()
+ "Compact JSON array is pretty-printed."
+ (with-temp-buffer
+ (insert "[1,2,3]")
+ (cj/json-format-buffer)
+ (should (string= (string-trim (buffer-string))
+ "[\n 1,\n 2,\n 3\n]"))))
+
+(ert-deftest test-prog-json--json-format-buffer-normal-nested ()
+ "Nested JSON is pretty-printed with sorted keys at all levels."
+ (with-temp-buffer
+ (insert "{\"b\":{\"d\":1,\"c\":2},\"a\":3}")
+ (cj/json-format-buffer)
+ (should (string-match-p "\"a\": 3" (buffer-string)))
+ (should (string-match-p "\"c\": 2" (buffer-string)))
+ ;; "a" should appear before "b" (sorted)
+ (should (< (string-match "\"a\"" (buffer-string))
+ (string-match "\"b\"" (buffer-string))))))
+
+(ert-deftest test-prog-json--json-format-buffer-normal-already-formatted ()
+ "Already-formatted JSON is unchanged."
+ (let ((formatted "{\n \"alpha\": 1,\n \"beta\": 2\n}\n"))
+ (with-temp-buffer
+ (insert formatted)
+ (cj/json-format-buffer)
+ (should (string= (buffer-string) formatted)))))
+
+;;; Boundary Cases
+
+(ert-deftest test-prog-json--json-format-buffer-boundary-empty-object ()
+ "Empty JSON object formats cleanly."
+ (with-temp-buffer
+ (insert "{}")
+ (cj/json-format-buffer)
+ (should (string= (string-trim (buffer-string)) "{}"))))
+
+(ert-deftest test-prog-json--json-format-buffer-boundary-empty-array ()
+ "Empty JSON array formats cleanly."
+ (with-temp-buffer
+ (insert "[]")
+ (cj/json-format-buffer)
+ (should (string= (string-trim (buffer-string)) "[]"))))
+
+(ert-deftest test-prog-json--json-format-buffer-boundary-scalar-string ()
+ "Bare JSON string scalar formats without error."
+ (with-temp-buffer
+ (insert "\"hello\"")
+ (cj/json-format-buffer)
+ (should (string= (string-trim (buffer-string)) "\"hello\""))))
+
+(ert-deftest test-prog-json--json-format-buffer-boundary-unicode ()
+ "JSON with unicode characters is preserved."
+ (with-temp-buffer
+ (insert "{\"emoji\":\"\\u2764\",\"name\":\"café\"}")
+ (cj/json-format-buffer)
+ (should (string-match-p "café" (buffer-string)))))
+
+;;; Fallback path — built-in formatter
+
+(ert-deftest test-prog-json--json-format-buffer-fallback-formats-without-jq ()
+ "Falls back to built-in formatter when jq is not found."
+ (cl-letf (((symbol-function 'executable-find) (lambda (_) nil)))
+ (with-temp-buffer
+ (insert "{\"b\":1,\"a\":2}")
+ (cj/json-format-buffer)
+ ;; Built-in formatter should pretty-print (key order may vary)
+ (should (string-match-p "\"a\"" (buffer-string)))
+ (should (string-match-p "\"b\"" (buffer-string)))
+ ;; Should be multi-line (formatted, not compact)
+ (should (> (count-lines (point-min) (point-max)) 1)))))
+
+;;; Error Cases
+
+(ert-deftest test-prog-json--json-format-buffer-error-invalid-json ()
+ "Invalid JSON produces an error, does not silently corrupt buffer."
+ (with-temp-buffer
+ (insert "{not valid json}")
+ (let ((original (buffer-string)))
+ ;; jq will fail on invalid JSON — buffer should not be emptied
+ (condition-case _err
+ (cj/json-format-buffer)
+ (error nil))
+ ;; Buffer should still have content (not wiped)
+ (should (> (length (buffer-string)) 0)))))
+
+(provide 'test-prog-json--json-format-buffer)
+;;; test-prog-json--json-format-buffer.el ends here