<commit_before>(defpackage :cl-minion-test
  (:use :common-lisp :fiveam :cl-minion)
  (:nicknames :minion-test)
  (:export :run-tests))

(in-package :cl-minion-test)

(def-suite cl-minion-test
  :description "Regression testing suite for Minion JSON parser.")

(test cl-minion-test
  (is (parse "{\"hello\":null}")
      '(:OBJ ((:KEY "hello" :NUL NIL))))
  (is (parse "{\"hello\":\"world\"}")
      '(:OBJ ((:KEY "hello" :STR "world"))))
  (is (parse "{\"hello\":{\"nested\":\"json\"}}")
      '(:OBJ ((:KEY "hello" :OBJ ((:KEY "nested" :STR "json"))))))
  (is (parse "{\"hello\":{\"integer\":123}}")
      '(:OBJ ((:KEY "hello" :OBJ ((:KEY "integer" :NUM 123))))))
  (is (parse "{\"hello\":{\"float\":123}}")
      '(:OBJ ((:KEY "hello" :OBJ ((:KEY "float" :NUM 123.23))))))
  (is (parse "[{\"hello\":\"world\",\"how\":\"are\",\"you\":\"today\"}]")
      '(:ARR ((:OBJ ((:KEY "hello" :STR "world") (:KEY "how" :STR "are")
                     (:KEY "you" :STR "today"))))))
  (is (parse "[true,false,false,null,true]")
      '(:ARR ((:TRU T) (:FAL NIL) (:FAL NIL) (:NUL NIL) (:TRU T))))
  (is (type-of (parse json-1)) 'CONS)
  (is (type-of (parse json-2)) 'CONS)
  (is (type-of (parse json-3)) 'CONS))

(defun time-minion (n)
  (time (loop :for i from 0 to n :do (parse json-3))))

(defun profile-minion (&key (clear nil))
  #+SBCL
  (let ((to-profile
          '(cl-minion:parse
            cl-minion::val
            cl-minion::arr
            cl-minion::obj
            cl-minion::str
            cl-minion::key
            cl-minion::lst
            cl-minion::tup
            cl-minion::lit
            cl-minion::num
            cl-minion::match
            cl-minion::match-if
            cl-minion::collect-char
            cl-minion::collect-literal
            cl-minion::collect*
            cl-minion::collect-number)))
    (when clear (sb-profile:reset))
    (sb-profile:profile to-profile)
    (parse json-3)
    (sb-profile:report)))

(defun run-tests (&optional (n 1000) (clear nil))
  (format t "RUNNING  REGRESSION TESTS...")
  (run! 'cl-minion-test)
  (format t "RUN ~d TIMES...~%" n)
  (time-minion n)
  (format t "RUN PROFILER...")
  (profile-minion :clear clear))

(defparameter json-1
  "{
  \"glossary\": {
    \"title\": \"example glossary\",
    \"GlossDiv\": {
      \"title\": \"S\",
      \"GlossList\": {
        \"GlossEntry\": {
          \"ID\": \"SGML\",
          \"SortAs\": \"SGML\",
          \"GlossTerm\": \"Standard Generalized Markup Language\",
          \"Acronym\": \"SGML\",
          \"Abbrev\": \"ISO 8879:1986\",
          \"GlossDef\": {
            \"para\": \"A meta-markup language, used to create markup languages such as DocBook.\",
            \"GlossSeeAlso\": [
              \"GML\",
              \"XML\"
            ]
          },
          \"GlossSee\": \"markup\"
        }
      }<commit_msg>simplify<commit_after>(defpackage :cl-minion-test
  (:use :common-lisp :fiveam :cl-minion)
  (:nicknames :minion-test)
  (:export :run-tests))

(in-package :cl-minion-test)

(def-suite cl-minion-test
  :description "Regression testing suite for Minion JSON parser.")

(test cl-minion-test
  (is (parse "{\"hello\":null}")
      '(:OBJ ((:KEY "hello" :NUL NIL))))
  (is (parse "{\"hello\":\"world\"}")
      '(:OBJ ((:KEY "hello" :STR "world"))))
  (is (parse "{\"hello\":{\"nested\":\"json\"}}")
      '(:OBJ ((:KEY "hello" :OBJ ((:KEY "nested" :STR "json"))))))
  (is (parse "{\"hello\":{\"integer\":123}}")
      '(:OBJ ((:KEY "hello" :OBJ ((:KEY "integer" :NUM 123))))))
  (is (parse "{\"hello\":{\"float\":123}}")
      '(:OBJ ((:KEY "hello" :OBJ ((:KEY "float" :NUM 123.23))))))
  (is (parse "[{\"hello\":\"world\",\"how\":\"are\",\"you\":\"today\"}]")
      '(:ARR ((:OBJ ((:KEY "hello" :STR "world") (:KEY "how" :STR "are")
                     (:KEY "you" :STR "today"))))))
  (is (parse "[true,false,false,null,true]")
      '(:ARR ((:TRU T) (:FAL NIL) (:FAL NIL) (:NUL NIL) (:TRU T))))
  (is (type-of (parse json-1)) 'CONS)
  (is (type-of (parse json-2)) 'CONS)
  (is (type-of (parse json-3)) 'CONS))

(defun run-tests (&key (n 1000) (clear nil) json-string )
  (format t "RUNNING  REGRESSION TESTS...")
  (run! 'cl-minion-test)
  (format t "RUN ~d TIMES...~%" n)
  (time (loop :for i from 0 to n :do (parse json-3)))
  (format t "RUN PROFILER...")
  #+SBCL
  (progn
    (when clear (sb-profile:reset))
    (sb-profile:profile cl-minion:parse
                        cl-minion::val
                        cl-minion::arr
                        cl-minion::obj
                        cl-minion::str
                        cl-minion::key
                        cl-minion::lst
                        cl-minion::tup
                        cl-minion::lit
                        cl-minion::num
                        cl-minion::match
                        cl-minion::match-if
                        cl-minion::collect-char
                        cl-minion::collect-literal
                        cl-minion::collect*
                        cl-minion::collect-number))
  (parse (or json-string json-3))
  (sb-profile:report)
  (sb-profile:unprofile))

(defparameter json-1
  "{
  \"glossary\": {
    \"title\": \"example glossary\",
    \"GlossDiv\": {
      \"title\": \"S\",
      \"GlossList\": {
        \"GlossEntry\": {
          \"ID\": \"SGML\",
          \"SortAs\": \"SGML\",
          \"GlossTerm\": \"Standard Generalized Markup Language\",
          \"Acronym\": \"SGML\",
          \"Abbrev\": \"ISO 8879:1986\",
          \"GlossDef\": {
            \"para\": \"A meta-markup language, used to create markup languages such as DocBook.\",
            \"GlossSeeAlso\": [
              \"GML\",
              \"XML\"
            ]
          },
          \"GlossSee\": \"markup\"
        }
      }
{'fraction_non_alphanumeric': 0.224662746454514, 'fraction_numerical': 0.011414735385679695, 'mean_word_length': 1.9295845997973657, 'pattern_counts': {'":': 52, '<': 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': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1026274', 'n_tokens_mistral': 2095, 'n_tokens_neox': 1986, 'n_words': 463}