<commit_before>(in-package :json-test)
(in-suite json)

(defmacro with-objects-as-hashtables(&body body)
  ;;For testing, keys are stored as strings
  `(let ((*json-object-factory* #'(lambda ()
                                   (make-hash-table :test #'equalp )))
        (*json-object-factory-add-key-value* #'(lambda (obj key value)
                                                 (setf (gethash key obj)
                                                       value)
                                                 obj))
        (*json-object-factory-return* #'identity))
    ,@body))
    
(test json-string()
   (is (string= (encode-json-to-string (format nil "hello~&hello"))
                 "\"hello\\nhello\""))
   (is (string= (encode-json-to-string (format nil "\"aquote"))
                 "\"\\\"aquote\"")))

(test json-literals
  (is (string= "true" (encode-json-to-string t)))
  (is (string= "null" (encode-json-to-string nil))))

(defun is-same-number(nr)
  "If it gets decoded back ok then it was encoded ok"
  (is (= nr (decode-json-from-string (encode-json-to-string nr)))))

(test json-number
  (is (string= "0" (encode-json-to-string 0)))
  (is (string= "13" (encode-json-to-string 13)))
  (is (string= "13.02" (encode-json-to-string 13.02)))

  (is-same-number 2e10)
  (is-same-number  -1.3234e-10)
  (is-same-number -1280.12356)
  (is-same-number 1d2)
  (is-same-number 1l2)
  (is-same-number 1s2)
  (is-same-number 1f2)
  (is-same-number 1e2))

(defun decode-then-encode (json)
  (with-objects-as-hashtables
    (assert (member (elt json 0) '(#\{ #\[ #\" ))) ;must be json
    (flet ((normalize (string)
             (remove #\Newline (remove #\Space string))))
      (let* ((decoded (decode-json-from-string json))
             (encoded (encode-json-to-string decoded)))
;;        (format t "Json:~a~&" json)
;;        (format t "Encoded:~a" encoded)    
        (is (string= (normalize json)
                     (normalize encoded)))))))


(test test-encode-json-alist
      (let ((alist `((:HELLO . 100)(:hi . 5)))
            (expected "{\"hello\":100,\"hi\":5}"))
        (is (string= (with-output-to-string (s) (encode-json-alist alist s))
                     expected))))

(test test-encode-json-alist-two
      (let ((alist `((HELLO . 100)(hi . 5)))
            (expected "{\"hello\":100,\"hi\":5}"))
        (is (string= (with-output-to-string (s) (encode-json-alist alist s))
                     expected))))

(test test-encode-json-alist-string
      (let ((alist `((:hello . "hej")(:hi . "tjena")))
            (expected "{\"hello\":\"hej\",\"hi\":\"tjena\"}"))
        (is (string= (with-output-to-string (s) (encode-json-alist alist s))
                     expected))))

(test test-encode-json-alist-camel-case
      (let ((alist `((:hello-message . "hej")(*also-starting-with-upper . "hej")))
            (expected "{\"helloMessage\":\"hej\",\"AlsoStartingWithUpper\":\"hej\"}"))
        (is (string= (with-output-to-string (s) (encode-json-alist alist s))
                     expected))))

(test encode-pass-2
  (decode-then-encode "[[[[[[[[[[[[[[[[[[[\"Not too deep\"]]]]]]]]]]]]]]]]]]]"))

(test encode-pass-3
  (decode-then-encode "{
    \"JSON Test Pattern pass3\": {
        \"The outermost value\": \"must be an object or array.\",
        \"In this test\": \"It is an object.\"
    }
}<commit_msg>simplify test that failed for the wrong reason<commit_after>(in-package :json-test)
(in-suite json)

(defmacro with-objects-as-hashtables(&body body)
  ;;For testing, keys are stored as strings
  `(let ((*json-object-factory* #'(lambda ()
                                   (make-hash-table :test #'equalp )))
        (*json-object-factory-add-key-value* #'(lambda (obj key value)
                                                 (setf (gethash key obj)
                                                       value)
                                                 obj))
        (*json-object-factory-return* #'identity))
    ,@body))
    
(test json-string()
   (is (string= (encode-json-to-string (format nil "hello~&hello"))
                 "\"hello\\nhello\""))
   (is (string= (encode-json-to-string (format nil "\"aquote"))
                 "\"\\\"aquote\"")))

(test json-literals
  (is (string= "true" (encode-json-to-string t)))
  (is (string= "null" (encode-json-to-string nil))))

(defun is-same-number(nr)
  "If it gets decoded back ok then it was encoded ok"
  (is (= nr (decode-json-from-string (encode-json-to-string nr)))))

(test json-number
  (is (string= "0" (encode-json-to-string 0)))
  (is (string= "13" (encode-json-to-string 13)))
  (is (string= "13.02" (encode-json-to-string 13.02)))

  (is-same-number 2e10)
  (is-same-number  -1.3234e-10)
  (is-same-number -1280.12356)
  (is-same-number 1d2)
  (is-same-number 1l2)
  (is-same-number 1s2)
  (is-same-number 1f2)
  (is-same-number 1e2))

(defun decode-then-encode (json)
  (with-objects-as-hashtables
    (assert (member (elt json 0) '(#\{ #\[ #\" ))) ;must be json
    (flet ((normalize (string)
             (remove #\Newline (remove #\Space string))))
      (let* ((decoded (decode-json-from-string json))
             (encoded (encode-json-to-string decoded)))
;;        (format t "Json:~a~&" json)
;;        (format t "Encoded:~a" encoded)    
        (is (string= (normalize json)
                     (normalize encoded)))))))


(test test-encode-json-alist
      (let ((alist `((:HELLO . 100)(:hi . 5)))
            (expected "{\"hello\":100,\"hi\":5}"))
        (is (string= (with-output-to-string (s) (encode-json-alist alist s))
                     expected))))

(test test-encode-json-alist-two
      (let ((alist `((HELLO . 100)(hi . 5)))
            (expected "{\"hello\":100,\"hi\":5}"))
        (is (string= (with-output-to-string (s) (encode-json-alist alist s))
                     expected))))

(test test-encode-json-alist-string
      (let ((alist `((:hello . "hej")(:hi . "tjena")))
            (expected "{\"hello\":\"hej\",\"hi\":\"tjena\"}"))
        (is (string= (with-output-to-string (s) (encode-json-alist alist s))
                     expected))))

(test test-encode-json-alist-camel-case
      (let ((alist `((:hello-message . "hej")(*also-starting-with-upper . "hej")))
            (expected "{\"helloMessage\":\"hej\",\"AlsoStartingWithUpper\":\"hej\"}"))
        (is (string= (with-output-to-string (s) (encode-json-alist alist s))
                     expected))))

(test encode-pass-2
  (decode-then-encode "[[[[[[[[[[[[[[[[[[[\"Not too deep\"]]]]]]]]]]]]]]]]]]]"))

(test encode-pass-3
  (decode-then-encode "{
    \"JSON Test Pattern pass3\": {
        \"The outermost value\": \"must be an object or array.\"
    }
}
{'fraction_non_alphanumeric': 0.2047255869597727, 'fraction_numerical': 0.018842530282637954, 'mean_word_length': 2.142857142857143, 'pattern_counts': {'":': 21, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5243125', 'n_tokens_mistral': 2376, 'n_tokens_neox': 2271, 'n_words': 502}