emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/parseclj a8e1de0d62 075/185: Merge pull request #4 from la


From: ELPA Syncer
Subject: [nongnu] elpa/parseclj a8e1de0d62 075/185: Merge pull request #4 from lambdaisland/edn-ast-split
Date: Tue, 28 Dec 2021 14:05:19 -0500 (EST)

branch: elpa/parseclj
commit a8e1de0d62d9a23f84a6fe16fe2d7ff2cf7862e0
Merge: 1cf0fb9d3f 496c965edc
Author: Arne Brasseur <arne.brasseur@gmail.com>
Commit: GitHub <noreply@github.com>

    Merge pull request #4 from lambdaisland/edn-ast-split
    
    Split EDN and AST handling into their own files
---
 .gitignore                      |   1 +
 .travis.yml                     |  25 +--
 Cask                            |  14 ++
 README.md                       |   2 +-
 benchmark/speed-comparison.el   |   2 +-
 clj-ast.el                      | 116 ++++++++++++
 clj-edn.el                      | 145 ++++++++++++++
 clj-lex.el                      |   4 +-
 clj-parse-test-runner.el        |  48 -----
 clj-parse.el                    | 124 +-----------
 test/clj-ast-test.el            |  68 +++++++
 test/clj-ast-unparse-test.el    | 166 +++++++++++++++++
 test/clj-edn-el-parity-test.el  | 286 ++++++++++++++++++++++++++++
 test/clj-edn-test.el            |  77 ++++++++
 {tests => test}/clj-lex-test.el |  10 +-
 test/clj-parse-test-data.el     | 298 +++++++++++++++++++++++++++++
 test/clj-parse-test.el          |  38 ++++
 test/test-helper.el             |  38 ++++
 tests/clj-parse-test.el         | 404 ----------------------------------------
 tests/edn-el-test-suite.el      | 281 ----------------------------
 20 files changed, 1278 insertions(+), 869 deletions(-)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000..d4691b73a4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+.cask
diff --git a/.travis.yml b/.travis.yml
index 16e2a68de7..5cfcd11bb1 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,20 +1,23 @@
 language: generic
 dist: trusty
 env:
-  - VERSION=25.2.2 EMACS=emacs-25.2 PACKAGE=emacs25
-  - VERSION=25.2.2 EMACS=emacs-25.2 PACKAGE=emacs25 CLJ_PARSE_LINT=true
-
+  - EMACS=emacs25
+  - EMACS=emacs-snapshot
 matrix:
   allow_failures:
-    - env: VERSION=25.2.2 EMACS=emacs-25.2 PACKAGE=emacs25 CLJ_PARSE_LINT=true
-
+    - env: EMACS=emacs-snapshot
 before_install:
+  # Emacs 25
   - sudo add-apt-repository -y ppa:kelleyk/emacs
+  # Nightly Emacs snapshot builds
+  - sudo add-apt-repository -y ppa:ubuntu-elisp/ppa
+  # Update and install the Emacs for our environment
   - sudo apt-get update -qq
-  - sudo apt-get install -qq $PACKAGE
-
+  - sudo apt-get install -qq -yy ${EMACS}
+  # Install and bootstrap cask
+  - travis_retry sh -c 'curl -fsSkL https://raw.github.com/cask/cask/master/go 
| python'
+  - export PATH="${HOME}/.cask/bin:$PATH"
+install:
+  - cask install
 script:
-  - $EMACS --version
-  - ls /usr/bin /usr/local/bin | grep emacs
-  - $EMACS --version | grep $VERSION
-  - $EMACS -batch -l clj-parse-test-runner.el
+  - cask exec ert-runner
diff --git a/Cask b/Cask
new file mode 100644
index 0000000000..528cd303fd
--- /dev/null
+++ b/Cask
@@ -0,0 +1,14 @@
+(source gnu)
+(source melpa)
+(source lambdaisland "https://lambdaisland.github.io/elpa/";)
+
+(package-file "clj-parse.el")
+
+(files "clj-lex.el"
+       "clj-edn.el"
+       "clj-ast.el")
+
+(development
+ (depends-on "a")
+;; (depends-on "edn") ;; the edn.el parity tests require some edn.el functions
+ (depends-on "ert-runner"))
diff --git a/README.md b/README.md
index 520561f21b..124801fd07 100644
--- a/README.md
+++ b/README.md
@@ -8,4 +8,4 @@ WIP
 
 &copy; 2017 Arne Brasseur
 
-Distributed under the terms of the [Mozilla Public License 
2.0](https://www.mozilla.org/media/MPL/2.0/index.txt). See LICENSE.
\ No newline at end of file
+Distributed under the terms of the GNU General Public License 3.0 or later. 
See LICENSE.
diff --git a/benchmark/speed-comparison.el b/benchmark/speed-comparison.el
index b50a405940..2529e782eb 100644
--- a/benchmark/speed-comparison.el
+++ b/benchmark/speed-comparison.el
@@ -14,7 +14,7 @@
       ;;(message fn)
       (with-current-buffer buff
         (let ((start (time-to-seconds (current-time))))
-          (clj-parse-edn)
+          (clj-edn-read)
           (setq clj-time (+ clj-time (- (time-to-seconds (current-time)) 
start))))
         (goto-char 1)
         (let ((start (time-to-seconds (current-time))))
diff --git a/clj-ast.el b/clj-ast.el
new file mode 100644
index 0000000000..c295d316e6
--- /dev/null
+++ b/clj-ast.el
@@ -0,0 +1,116 @@
+;;; clj-ast.el --- Clojure parser/unparser              -*- lexical-binding: 
t; -*-
+
+;; Copyright (C) 2017  Arne Brasseur
+
+;; Author: Arne Brasseur <arne@arnebrasseur.net>
+
+;; This file is not part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; Parse Clojure code to an AST, and unparse back to code.
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Parser
+
+(defun clj-parse--make-node (type position &rest kvs)
+  (apply 'a-list ':node-type type ':position position kvs))
+
+(defun clj-ast--reduce-leaf (stack token)
+  (if (eq (clj-lex-token-type token) :whitespace)
+      stack
+    (cons
+     (clj-parse--make-node (clj-lex-token-type token) (a-get token 'pos)
+                           ':form (a-get token 'form)
+                           ':value (clj-parse--leaf-token-value token))
+     stack)))
+
+(defun clj-ast--reduce-node (stack opener-token children)
+  (let* ((pos (a-get opener-token 'pos))
+         (type (clj-lex-token-type opener-token))
+         (type (cl-case type
+                 (:lparen :list)
+                 (:lbracket :vector)
+                 (:lbrace :map)
+                 (t type))))
+    (cl-case type
+      (:root (clj-parse--make-node :root 0 :children children))
+      (:discard stack)
+      (:tag (list (clj-parse--make-node :tag
+                                        pos
+                                        :tag (intern (substring (a-get 
opener-token 'form) 1))
+                                        :children children)))
+      (t (cons
+          (clj-parse--make-node type pos :children children)
+          stack)))))
+
+(defun clj-ast-parse ()
+  "Parse Clojure code in buffer to AST.
+
+Parses code in the current buffer, starting from the current
+position of (point)."
+  (clj-parse-reduce #'clj-ast--reduce-leaf #'clj-ast--reduce-node))
+
+(defun clj-ast-parse-str (s)
+  "Parse Clojure code in string S to AST."
+  (with-temp-buffer
+    (insert s)
+    (goto-char 1)
+    (clj-ast-parse)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Unparser
+
+(defun clj-ast-unparse-collection (nodes ld rd)
+  (insert ld)
+  (when-let (node (car nodes))
+    (clj-ast-unparse node))
+  (seq-doseq (node (cdr nodes))
+    (insert " ")
+    (clj-ast-unparse node))
+  (insert rd))
+
+(defun clj-ast-unparse-tag (node)
+  (progn
+    (insert "#")
+    (insert (symbol-name (a-get node :tag)))
+    (insert " ")
+    (clj-ast-unparse (car (a-get node :children)))))
+
+(defun clj-ast-unparse (node)
+  (if (clj-parse--is-leaf? node)
+      (insert (alist-get ':form node))
+    (let ((subnodes (alist-get ':children node)))
+      (cl-case (a-get node ':node-type)
+        (:root (clj-ast-unparse-collection subnodes "" ""))
+        (:list (clj-ast-unparse-collection subnodes "(" ")"))
+        (:vector (clj-ast-unparse-collection subnodes "[" "]"))
+        (:set (clj-ast-unparse-collection subnodes "#{" "}"))
+        (:map (clj-ast-unparse-collection subnodes "{" "}"))
+        (:tag (clj-ast-unparse-tag node))))))
+
+(defun clj-ast-unparse-str (data)
+  (with-temp-buffer
+    (clj-ast-unparse data)
+    (buffer-substring-no-properties (point-min) (point-max))))
+
+(provide 'clj-ast)
+
+;;; clj-ast.el ends here
diff --git a/clj-edn.el b/clj-edn.el
new file mode 100644
index 0000000000..d509c6c4b0
--- /dev/null
+++ b/clj-edn.el
@@ -0,0 +1,145 @@
+;;; clj-edn.el --- EDN reader/writer              -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017  Arne Brasseur
+
+;; Author: Arne Brasseur <arne@arnebrasseur.net>
+
+;; This file is not part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; The EDN <-> Elisp reader and printer
+
+;;; Code:
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Reader
+
+(defvar clj-edn-default-tag-readers
+  (a-list 'inst (lambda (s)
+                  (cl-list* 'edn-inst (date-to-time s)))
+          'uuid (lambda (s)
+                  (list 'edn-uuid s)))
+  "Default reader functions for handling tagged literals in EDN.
+These are the ones defined in the EDN spec, #inst and #uuid. It
+is not recommended you change this variable, as this globally
+changes the behavior of the EDN reader. Instead pass your own
+handlers as an optional argument to the reader functions.")
+
+(defun clj-edn-reduce-leaf (stack token)
+  (if (member (clj-lex-token-type token) (list :whitespace :comment))
+      stack
+    (cons (clj-parse--leaf-token-value token) stack)))
+
+(defun clj-edn-reduce-node (tag-readers)
+  (lambda (stack opener-token children)
+    (let ((token-type (clj-lex-token-type opener-token)))
+      (if (member token-type '(:root :discard))
+          stack
+        (cons
+         (cl-case token-type
+           (:lparen children)
+           (:lbracket (apply #'vector children))
+           (:set (list 'edn-set children))
+           (:lbrace (let* ((kvs (seq-partition children 2))
+                           (hash-map (make-hash-table :test 'equal :size 
(length kvs))))
+                      (seq-do (lambda (pair)
+                                (puthash (car pair) (cadr pair) hash-map))
+                              kvs)
+                      hash-map))
+           (:tag (let* ((tag (intern (substring (a-get opener-token 'form) 1)))
+                        (reader (a-get tag-readers tag :missing)))
+                   (when (eq :missing reader)
+                     (user-error "No reader for tag #%S in %S" tag (a-keys 
tag-readers)))
+                   (funcall reader (car children)))))
+         stack)))))
+
+(defun clj-edn-read (&optional tag-readers)
+  (clj-parse-reduce #'clj-edn-reduce-leaf
+                    (clj-edn-reduce-node (a-merge clj-edn-default-tag-readers 
tag-readers))))
+
+(defun clj-edn-read-str (s &optional tag-readers)
+  (with-temp-buffer
+    (insert s)
+    (goto-char 1)
+    (car (clj-edn-read tag-readers))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Printer
+
+
+(defun clj-edn-print-seq (coll)
+  (clj-edn-print (elt coll 0))
+  (let ((next (seq-drop coll 1)))
+    (when (not (seq-empty-p next))
+      (insert " ")
+      (clj-edn-print-seq next))))
+
+(defun clj-edn-print-kvs (map)
+  (let ((keys (a-keys map)))
+    (clj-edn-print (car keys))
+    (insert " ")
+    (clj-edn-print (a-get map (car keys)))
+    (let ((next (cdr keys)))
+      (when (not (seq-empty-p next))
+        (insert ", ")
+        (clj-edn-print-kvs next)))))
+
+(defun clj-edn-print (datum)
+  (cond
+   ((or (null datum) (numberp datum))
+    (prin1 datum (current-buffer)))
+
+   ((stringp datum)
+    (insert "\"")
+    (seq-doseq (char datum)
+      (insert (cl-case char
+                (?\t "\\t")
+                (?\f "\\f")
+                (?\" "\\\"")
+                (?\r "\\r")
+                (?\n"foo\t" "\\n")
+                (?\\ "\\\\")
+                (t (char-to-string char)))))
+    (insert "\""))
+
+   ((eq t datum)
+    (insert "true"))
+
+   ((symbolp datum)
+    (insert (symbol-name datum)))
+
+   ((vectorp datum) (insert "[") (clj-edn-print-seq datum) (insert "]"))
+
+   ((consp datum)
+    (cond
+     ((eq 'edn-set (car datum))
+      (insert "#{") (clj-edn-print-seq (cadr datum)) (insert "}"))
+     (t (insert "(") (clj-edn-print-seq datum) (insert ")"))))
+
+   ((hash-table-p datum)
+    (insert "{") (clj-edn-print-kvs datum) (insert "}"))))
+
+(defun clj-edn-print-str (datum)
+  (with-temp-buffer
+    (clj-edn-print datum)
+    (buffer-substring-no-properties (point-min) (point-max))))
+
+(provide 'clj-edn)
+
+;;; clj-edn.el ends here
diff --git a/clj-lex.el b/clj-lex.el
index 99b5264d34..f85818ecfb 100644
--- a/clj-lex.el
+++ b/clj-lex.el
@@ -25,15 +25,13 @@
 
 ;; A reader for EDN data files and parser for Clojure source files.
 
-(require 'dash)
-
 (defun clj-lex-token (type form pos &rest args)
   `((type . ,type)
     (form . ,form)
     (pos  . ,pos)
     ,@(mapcar (lambda (pair)
                 (cons (car pair) (cadr pair)))
-              (-partition 2 args))))
+              (seq-partition args 2))))
 
 (defun clj-lex-token-type (token)
   (and (listp token)
diff --git a/clj-parse-test-runner.el b/clj-parse-test-runner.el
deleted file mode 100644
index 4a49138c9a..0000000000
--- a/clj-parse-test-runner.el
+++ /dev/null
@@ -1,48 +0,0 @@
-;; Script used for the Travis build
-
-(setq package-archives
-      '(("gnu" . "https://elpa.gnu.org/packages/";)
-        ("melpa" . "https://melpa.org/packages/";)
-        ("melpa-stable" . "https://stable.melpa.org/packages/";)
-        ("plexus-elpa" . "https://plexus.github.io/elpa/";)))
-
-
-(package-initialize)
-(package-refresh-contents)
-
-;; Emacs before 25.1
-(when (not (fboundp 'let-alist))
-  (package-install 'let-alist))
-
-(package-install 'package-lint)
-(package-install 'a)
-(package-install 'dash)
-(package-install 'edn) ;; required for the edn test suite
-
-(setq clj-parse-load-files '("clj-parse.el"
-                             "clj-lex.el"
-                             "tests/clj-parse-test.el"
-                             "tests/clj-lex-test.el"
-                             "tests/edn-el-test-suite.el"))
-
-(let ((pwd (replace-regexp-in-string "\n\\'" "" (shell-command-to-string 
"pwd"))))
-
-  (add-to-list 'load-path pwd)
-
-  (dolist (file clj-parse-load-files)
-    (load (concat pwd "/" file)))
-
-  (if (getenv "CLJ_PARSE_LINT")
-      (let ((success t))
-        (dolist (file clj-parse-load-files)
-          (with-temp-buffer
-            (insert-file-contents file t)
-            (emacs-lisp-mode)
-            (let ((checking-result (package-lint-buffer)))
-              (when checking-result
-                (setq success nil)
-                (message "In `%s':" file)
-                (pcase-dolist (`(,line ,col ,type ,message) checking-result)
-                  (message "  at %d:%d: %s: %s" line col type message))))))
-        (kill-emacs (if success 0 1)))
-    (ert-run-tests-batch-and-exit)))
diff --git a/clj-parse.el b/clj-parse.el
index c3d9a6f3e5..cfccdb59f8 100644
--- a/clj-parse.el
+++ b/clj-parse.el
@@ -4,7 +4,7 @@
 
 ;; Author: Arne Brasseur <arne@arnebrasseur.net>
 ;; Keywords: lisp
-;; Package-Requires: ((dash "2.12.0") (emacs "25") (a "0.1.0alpha2"))
+;; Package-Requires: ((emacs "25") (a "0.1.0alpha4"))
 ;; Version: 0.1.0
 
 ;; This file is not part of GNU Emacs.
@@ -30,10 +30,12 @@
 
 ;;; Code:
 
-(require 'a)
-(require 'dash)
 (require 'cl-lib)
+(require 'a)
+
 (require 'clj-lex)
+(require 'clj-edn)
+(require 'clj-ast)
 
 (defvar clj-parse--leaf-tokens '(:whitespace
                                  :comment
@@ -117,7 +119,7 @@
     (:rparen :lparen)
     (:rbracket :lbracket)
     (:rbrace (clj-lex-token-type
-              (-find (lambda (token) (member (clj-lex-token-type token) 
'(:lbrace :set))) stack)))))
+              (seq-find (lambda (token) (member (clj-lex-token-type token) 
'(:lbrace :set))) stack)))))
 
 (defun clj-parse--reduce-coll (stack closer-token reduceN)
   "Reduce collection based on the top of the stack"
@@ -161,120 +163,6 @@
     stack))
 
 
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; Reducer implementations
-
-(defun clj-parse--make-node (type position &rest kvs)
-  (apply 'a-list ':node-type type ':position position kvs))
-
-;; AST
-
-(defun clj-parse--ast-reduce-leaf (stack token)
-  (if (eq (clj-lex-token-type token) :whitespace)
-      stack
-    (push
-     (clj-parse--make-node (clj-lex-token-type token) (a-get token 'pos)
-                           ':form (a-get token 'form)
-                           ':value (clj-parse--leaf-token-value token))
-     stack)))
-
-(defun clj-parse--ast-reduce-node (stack opener-token children)
-  (let* ((pos (a-get opener-token 'pos))
-         (type (cl-case (clj-lex-token-type opener-token)
-                 (:root :root)
-                 (:lparen :list)
-                 (:lbracket :vector)
-                 (:set :set)
-                 (:lbrace :map)
-                 (:discard :discard))))
-    (cl-case type
-      (:root (clj-parse--make-node :root 0 ':children children))
-      (:discard stack)
-      (t (push
-          (clj-parse--make-node type pos
-                                ':children children)
-          stack)))))
-
-(defun clj-parse-ast ()
-  (clj-parse-reduce #'clj-parse--ast-reduce-leaf #'clj-parse--ast-reduce-node))
-
-; Elisp
-
-(defun clj-parse--edn-reduce-leaf (stack token)
-  (if (member (clj-lex-token-type token) (list :whitespace :comment))
-      stack
-    (push (clj-parse--leaf-token-value token) stack)))
-
-(defun clj-parse--edn-reduce-node (tag-readers)
-  (lambda (stack opener-token children)
-    (let ((token-type (clj-lex-token-type opener-token)))
-      (if (member token-type '(:root :discard))
-          stack
-        (push
-         (cl-case token-type
-           (:lparen children)
-           (:lbracket (apply #'vector children))
-           (:set (list 'edn-set children))
-           (:lbrace (let* ((kvs (seq-partition children 2))
-                           (hash-map (make-hash-table :test 'equal :size 
(length kvs))))
-                      (seq-do (lambda (pair)
-                                (puthash (car pair) (cadr pair) hash-map))
-                              kvs)
-                      hash-map))
-           (:tag (let* ((tag (intern (substring (a-get opener-token 'form) 1)))
-                        (reader (a-get tag-readers tag :missing)))
-                   (when (eq :missing reader)
-                     (user-error "No reader for tag #%S in %S" tag (a-keys 
tag-readers)))
-                   (funcall reader (car children)))))
-         stack)))))
-
-(defvar clj-edn-default-tag-readers
-  (a-list 'inst (lambda (s)
-                  (cl-list* 'edn-inst (date-to-time s)))
-          'uuid (lambda (s)
-                  (list 'edn-uuid s)))
-  "Default reader functions for handling tagged literals in EDN.
-These are the ones defined in the EDN spec, #inst and #uuid. It
-is not recommended you change this variable, as this globally
-changes the behavior of the EDN reader. Instead pass your own
-handlers as an optional argument to the reader functions.")
-
-(defun clj-parse-edn (&optional tag-readers)
-  (clj-parse-reduce #'clj-parse--edn-reduce-leaf
-                    (clj-parse--edn-reduce-node (a-merge 
clj-edn-default-tag-readers tag-readers))))
-
-(defun clj-parse-edn-str (s &optional tag-readers)
-  (with-temp-buffer
-    (insert s)
-    (goto-char 1)
-    (car (clj-parse-edn tag-readers))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Printer implementations
-
-;; AST
-
-(defun clj-parse--reduce-string-leaf (leaf)
-  (alist-get ':form leaf))
-
-(defun clj-parse--string-with-delimiters (nodes ld rd)
-  (concat ld
-          (mapconcat #'clj-parse-ast-print nodes " ")
-          rd))
-
-(defun clj-parse-ast-print (node)
-  (if (clj-parse--is-leaf? node)
-      (clj-parse--reduce-string-leaf node)
-    (let ((subnodes (alist-get ':children node)))
-      (cl-case (a-get node ':node-type)
-        (:root (clj-parse--string-with-delimiters subnodes "" ""))
-        (:list (clj-parse--string-with-delimiters subnodes "(" ")"))
-        (:vector (clj-parse--string-with-delimiters subnodes "[" "]"))
-        (:set (clj-parse--string-with-delimiters subnodes "#{" "}"))
-        (:map (clj-parse--string-with-delimiters subnodes "{" "}"))
-        ;; tagged literals
-        ))))
-
 (provide 'clj-parse)
 
 ;;; clj-parse.el ends here
diff --git a/test/clj-ast-test.el b/test/clj-ast-test.el
new file mode 100644
index 0000000000..5b383da516
--- /dev/null
+++ b/test/clj-ast-test.el
@@ -0,0 +1,68 @@
+;;; clj-ast-test.el --- Unit tests for AST parsing/unparsing
+
+;; Copyright (C) 2017  Arne Brasseur
+
+;; Author: Arne Brasseur <arne@arnebrasseur.net>
+
+;; This file is not part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary
+
+;; Unit tests for AST parsing/unparsing
+
+;;; Code
+
+(require 'ert)
+(require 'clj-ast)
+
+(load "test/clj-parse-test-data.el")
+
+(defmacro define-clj-ast-parse-tests ()
+  `(progn
+     ,@(mapcar
+        (lambda (pair)
+          (let ((name (car pair))
+                (data (cdr pair)))
+            (if (and (a-get data :source) (a-get data :ast))
+                (let ((test-name (intern (concat "clj-ast-parse:" name))))
+                  `(ert-deftest ,test-name ()
+                     :tags '(clj-ast)
+                     (with-temp-buffer
+                       (insert ,(a-get data :source))
+                       (goto-char 1)
+                       (should (a-equal (clj-ast-parse) ',(a-get data 
:ast)))))))))
+        clj-parse-test-data)))
+
+(defmacro define-clj-ast-roundtrip-tests ()
+  `(progn
+     ,@(mapcar
+        (lambda (pair)
+          (let ((name (car pair))
+                (data (cdr pair)))
+            (if (and (a-get data :ast) (a-get data :source))
+                (let ((test-name (intern (concat "clj-ast-rountrip:" name))))
+                  `(ert-deftest ,test-name ()
+                     :tags '(clj-ast-rountrip)
+                     (should (a-equal (clj-ast-parse-str (clj-ast-unparse-str 
',(a-get data :ast))) ',(a-get data :ast))))))))
+        clj-parse-test-data)))
+
+
+(define-clj-ast-roundtrip-tests)
+(define-clj-ast-parse-tests)
+
+;;; clj-ast-test.el ends here
diff --git a/test/clj-ast-unparse-test.el b/test/clj-ast-unparse-test.el
new file mode 100644
index 0000000000..798aba4f32
--- /dev/null
+++ b/test/clj-ast-unparse-test.el
@@ -0,0 +1,166 @@
+;;; clj-ast-unparse-test.el --- Print Clojure AST back to code - tests
+
+;; Copyright (C) 2017  Arne Brasseur
+
+;; Author: Arne Brasseur <arne@arnebrasseur.net>
+
+;; This file is not part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; Print Clojure AST back to code - tests
+
+;;; Code:
+
+(require 'ert)
+(require 'clj-ast)
+
+;;; Printer modes
+;; ----------------------------------------------------------------------------
+
+(ert-deftest clj-ast-unparse-list ()
+  (should (equal "(0 1 2)"
+                 (clj-ast-unparse-str '((:node-type . :root)
+                                        (:position . 0)
+                                        (:children . (((:node-type . :list)
+                                                       (:position . 1)
+                                                       (:children . 
(((:node-type . :number)
+                                                                      
(:position . 2)
+                                                                      (:form . 
"0")
+                                                                      (:value 
. 0))
+                                                                     
((:node-type . :number)
+                                                                      
(:position . 4)
+                                                                      (:form . 
"1")
+                                                                      (:value 
. 1))
+                                                                     
((:node-type . :number)
+                                                                      
(:position . 6)
+                                                                      (:form . 
"2")
+                                                                      (:value 
. 2))))))))))))
+
+(ert-deftest clj-ast-unparse-empty-list ()
+  (should (equal "()"
+                 (clj-ast-unparse-str '((:node-type . :root)
+                                        (:position . 0)
+                                        (:children . (((:node-type . :list)
+                                                       (:position . 1)
+                                                       (:children . 
nil)))))))))
+
+(ert-deftest clj-ast-unparse-nested-list ()
+  (should (equal "((.9 abc (true) (hello)))"
+                 (clj-ast-unparse-str '((:node-type . :root)
+                                        (:position . 0)
+                                        (:children . (((:node-type . :list)
+                                                       (:position . 1)
+                                                       (:children . 
(((:node-type . :list)
+                                                                      
(:position . 2)
+                                                                      
(:children ((:node-type . :number)
+                                                                               
   (:position . 3)
+                                                                               
   (:form . ".9")
+                                                                               
   (:value . 0.9))
+                                                                               
  ((:node-type . :symbol)
+                                                                               
   (:position . 6)
+                                                                               
   (:form . "abc")
+                                                                               
   (:value . abc))
+                                                                               
  ((:node-type . :list)
+                                                                               
   (:position . 10)
+                                                                               
   (:children ((:node-type . :true)
+                                                                               
               (:position . 11)
+                                                                               
               (:form . "true")
+                                                                               
               (:value . t))))
+                                                                               
  ((:node-type . :list)
+                                                                               
   (:position . 17)
+                                                                               
   (:children ((:node-type . :symbol)
+                                                                               
               (:position . 18)
+                                                                               
               (:form . "hello")
+                                                                               
               (:value . hello))))))))))))))))
+
+(ert-deftest clj-ast-unparse-string ()
+  (should (equal "\"abc hello \\t\\\"x\""
+                 (clj-ast-unparse-str '((:node-type . :root)
+                                        (:position . 0)
+                                        (:children . (((:node-type . :string)
+                                                       (:position . 1)
+                                                       (:form . "\"abc hello 
\\t\\\"x\"")
+                                                       (:value . "abc hello 
\t\"x")))))))))
+
+(ert-deftest clj-ast-unparse-chars ()
+  (should (equal "(\\newline \\return \\space \\tab \\a \\b \\c \\u0078 
\\o171)"
+                 (clj-ast-unparse-str '((:node-type . :root)
+                                        (:position . 0)
+                                        (:children . (((:node-type . :list)
+                                                       (:position . 1)
+                                                       (:children . 
(((:node-type . :character) (:position . 2) (:form . "\\newline") (:value . 
?\n))
+                                                                     
((:node-type . :character) (:position . 11) (:form . "\\return") (:value . ?\r))
+                                                                     
((:node-type . :character) (:position . 19) (:form . "\\space") (:value . 32))
+                                                                     
((:node-type . :character) (:position . 26) (:form . "\\tab") (:value . ?\t))
+                                                                     
((:node-type . :character) (:position . 31) (:form . "\\a") (:value . ?a))
+                                                                     
((:node-type . :character) (:position . 34) (:form . "\\b") (:value . ?b))
+                                                                     
((:node-type . :character) (:position . 37) (:form . "\\c") (:value . ?c))
+                                                                     
((:node-type . :character) (:position . 40) (:form . "\\u0078") (:value . ?x))
+                                                                     
((:node-type . :character) (:position . 47) (:form . "\\o171") (:value . 
?y)))))))))
+                 )))
+
+(ert-deftest clj-ast-unparse-keyword ()
+  (should (equal ":foo-bar"
+                 (clj-ast-unparse-str '((:node-type . :root)
+                                        (:position . 0)
+                                        (:children . (((:node-type . :keyword)
+                                                       (:position . 1)
+                                                       (:form . ":foo-bar")
+                                                       (:value . 
:foo-bar)))))))))
+
+(ert-deftest clj-ast-unparse-vector ()
+  (should (equal "[123]"
+                 (clj-ast-unparse-str '((:node-type . :root)
+                                        (:position . 0)
+                                        (:children . (((:node-type . :vector)
+                                                       (:position . 1)
+                                                       (:children . 
(((:node-type . :number)
+                                                                      
(:position . 2)
+                                                                      (:form . 
"123")
+                                                                      (:value 
. 123))))))))))))
+
+(ert-deftest clj-ast-unparse-map ()
+  (should (equal "{:count 123}"
+                 (clj-ast-unparse-str '((:node-type . :root)
+                                        (:position . 0)
+                                        (:children . (((:node-type . :map)
+                                                       (:position . 1)
+                                                       (:children . 
(((:node-type . :keyword)
+                                                                      
(:position . 2)
+                                                                      (:form . 
":count")
+                                                                      (:value 
. :count))
+                                                                     
((:node-type . :number)
+                                                                      
(:position . 9)
+                                                                      (:form . 
"123")
+                                                                      (:value 
. 123))))))))))))
+
+(ert-deftest clj-ast-unparse-set ()
+  (should (equal "#{:x}"
+                 (clj-ast-unparse-str '((:node-type . :root)
+                                        (:position . 0)
+                                        (:children . (((:node-type . :set)
+                                                       (:position . 1)
+                                                       (:children . 
(((:node-type . :keyword)
+                                                                      
(:position . 3)
+                                                                      (:form . 
":x")
+                                                                      (:value 
. :x))))))))))))
+
+(provide 'clj-unparse-test)
+
+;;; clj-ast-unparse-test.el ends here
diff --git a/test/clj-edn-el-parity-test.el b/test/clj-edn-el-parity-test.el
new file mode 100644
index 0000000000..bae4d41609
--- /dev/null
+++ b/test/clj-edn-el-parity-test.el
@@ -0,0 +1,286 @@
+;;; edn-el-parity.el --- Tests from edn.el
+
+;; Author: Lars Andersen <expez@expez.com>, Arne Brasseur 
<arne@arnebrasseur.net>
+
+;; Copyright (C) 2015  Lars Andersen
+
+;; This file is not part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; These tests are copied verbatim from the edn.el source, and adapted to use
+;; our API. This way we assure that clj-parse can act as a drop-in replacement
+;; for edn.el.
+
+;;; Code:
+
+(require 'ert)
+(require 'clj-parse)
+(eval-when-compile (require 'subr-x)) ;; for things like hash-table-keys
+
+(ert-deftest whitespace ()
+  (should (null (clj-edn-read-str "")))
+  (should (null (clj-edn-read-str " ")))
+  (should (null (clj-edn-read-str "   ")))
+  (should (null (clj-edn-read-str "    ")))
+  (should (null (clj-edn-read-str "            ")))
+  (should (null (clj-edn-read-str ",")))
+  (should (null (clj-edn-read-str ",,,,")))
+  (should (null (clj-edn-read-str "      , ,\n")))
+  (should (null (clj-edn-read-str "\n ,,       ")))
+  (should (equal [a b c d] (clj-edn-read-str "[a ,,,,,, b,,,,,c ,d]"))))
+
+(ert-deftest symbols ()
+  :tags '(edn symbol)
+  (should (equal 'foo (clj-edn-read-str "foo")))
+  (should (equal 'foo\. (clj-edn-read-str "foo.")))
+  (should (equal '%foo\. (clj-edn-read-str "%foo.")))
+  (should (equal 'foo/bar (clj-edn-read-str "foo/bar")))
+  (equal 'some\#sort\#of\#symbol (clj-edn-read-str "some#sort#of#symbol"))
+  (equal 'truefalse (clj-edn-read-str "truefalse"))
+  (equal 'true. (clj-edn-read-str "true."))
+  (equal '/ (clj-edn-read-str "/"))
+  (should (equal '.true (clj-edn-read-str ".true")))
+  (should (equal 'some:sort:of:symbol (clj-edn-read-str 
"some:sort:of:symbol")))
+  (equal 'foo-bar (clj-edn-read-str "foo-bar"))
+  (should (equal '+some-symbol (clj-edn-read-str "+some-symbol")))
+  (should (equal '-symbol (clj-edn-read-str "-symbol"))))
+
+(ert-deftest booleans ()
+  :tags '(edn boolean)
+  (should (equal t (clj-edn-read-str "true")))
+  (should (equal nil (clj-edn-read-str "false "))))
+
+(ert-deftest characters ()
+  :tags '(edn characters)
+  (should (equal 97 (clj-edn-read-str "\\a")))
+  (should (equal 960 (clj-edn-read-str "\\u03C0")))
+  ;;(should (equal 'newline (clj-edn-read-str "\\newline")))
+  )
+
+(ert-deftest elision ()
+  :tags '(edn elision)
+  (should-not (clj-edn-read-str "#_foo"))
+  (should-not (clj-edn-read-str "#_ 123"))
+  (should-not (clj-edn-read-str "#_:foo"))
+  (should-not (clj-edn-read-str "#_ \\a"))
+  (should-not (clj-edn-read-str "#_
+\"foo\""))
+  (should-not (clj-edn-read-str "#_ (1 2 3)"))
+  (should (equal '(1 3) (clj-edn-read-str "(1 #_ 2 3)")))
+  (should (equal '[1 2 3 4] (clj-edn-read-str "[1 2 #_[4 5 6] 3 4]")))
+  (should (map-equal (make-seeded-hash-table :foo :bar)
+                     (clj-edn-read-str "{:foo #_elided :bar}")))
+  (should (equal '(edn-set (1 2 3 4))
+                 (clj-edn-read-str "#{1 2 #_[1 2 3] 3 #_ (1 2) 4}")))
+  (should (equal [a d] (clj-edn-read-str "[a #_ ;we are discarding what comes 
next
+ c d]"))))
+
+(ert-deftest string ()
+  :tags '(edn string)
+  (should (equal "this is a string" (clj-edn-read-str "\"this is a string\"")))
+  (should (equal "this has an escaped \"quote in it"
+                 (clj-edn-read-str "\"this has an escaped \\\"quote in it\"")))
+  (should (equal "foo\tbar" (clj-edn-read-str "\"foo\\tbar\"")))
+  (should (equal "foo\nbar" (clj-edn-read-str "\"foo\\nbar\"")))
+  (should (equal "this is a string \\ that has an escaped backslash"
+                 (clj-edn-read-str "\"this is a string \\\\ that has an 
escaped backslash\"")))
+  (should (equal "[" (clj-edn-read-str "\"[\""))))
+
+(ert-deftest keywords ()
+  :tags '(edn keywords)
+  (should (equal :namespace\.of\.some\.length/keyword-name
+                 (clj-edn-read-str ":namespace.of.some.length/keyword-name")))
+  (should (equal :\#/\# (clj-edn-read-str ":#/#")))
+  (should (equal :\#/:a (clj-edn-read-str ":#/:a")))
+  (should (equal :\#foo (clj-edn-read-str ":#foo"))))
+
+(ert-deftest integers ()
+  :tags '(edn integers)
+  (should (= 0 (clj-edn-read-str "0")))
+  (should (= 0 (clj-edn-read-str "+0")))
+  (should (= 0 (clj-edn-read-str "-0")))
+  (should (= 100 (clj-edn-read-str "100")))
+  (should (= -100 (clj-edn-read-str "-100"))))
+
+(ert-deftest floats ()
+  :tags '(edn floats)
+  (should (= 12.32 (clj-edn-read-str "12.32")))
+  (should (= -12.32 (clj-edn-read-str "-12.32")))
+  (should (= 9923.23 (clj-edn-read-str "+9923.23")))
+  (should (= 4.5e+044 (clj-edn-read-str "45e+43")))
+  (should (= -4.5e-042 (clj-edn-read-str "-45e-43")))
+  (should (= 4.5e+044 (clj-edn-read-str "45E+43"))))
+
+(ert-deftest lists ()
+  :tags '(edn lists)
+  (should-not (clj-edn-read-str "()"))
+  (should (equal '(1 2 3) (clj-edn-read-str "( 1 2 3)")))
+  (should (equal '(12.1 ?a foo :bar) (clj-edn-read-str "(12.1 \\a foo :bar)")))
+  (should (equal '((:foo bar :bar 12)) (clj-edn-read-str "( (:foo bar :bar 
12))")))
+  (should (equal
+           '(defproject com\.thortech/data\.edn "0.1.0-SNAPSHOT")
+           (clj-edn-read-str "(defproject com.thortech/data.edn 
\"0.1.0-SNAPSHOT\")"))))
+
+(ert-deftest vectors ()
+  :tags '(edn vectors)
+  (should (equal [] (clj-edn-read-str "[]")))
+  (should (equal [] (clj-edn-read-str "[ ]")))
+  (should (equal '[1 2 3] (clj-edn-read-str "[ 1 2 3 ]")))
+  (should (equal '[12.1 ?a foo :bar] (clj-edn-read-str "[ 12.1 \\a foo 
:bar]")))
+  (should (equal '[[:foo bar :bar 12]] (clj-edn-read-str "[[:foo bar :bar 
12]]")))
+  (should (equal '[( :foo bar :bar 12 ) "foo"]
+                 (clj-edn-read-str "[(:foo bar :bar 12) \"foo\"]")))
+  (should (equal '[/ \. * ! _ \? $ % & = - +]
+                 (clj-edn-read-str "[/ . * ! _ ? $ % & = - +]")))
+  (should (equal
+           ;;[99 newline return space tab]
+           [99 10 13 32 9]
+           (clj-edn-read-str "[\\c \\newline \\return \\space \\tab]"))))
+
+(defun map-equal (m1 m2)
+  (and (and (hash-table-p m1) (hash-table-p m2))
+       (eq (hash-table-test m1) (hash-table-test m2))
+       (= (hash-table-count m1) (hash-table-count m2))
+       (equal (hash-table-keys m1) (hash-table-keys m2))
+       (equal (hash-table-values m1) (hash-table-values m2))))
+
+(defun make-seeded-hash-table (&rest keys-and-values)
+  (let ((m (make-hash-table :test #'equal)))
+    (while keys-and-values
+      (puthash (pop keys-and-values) (pop keys-and-values) m))
+    m))
+
+(ert-deftest maps ()
+  :tags '(edn maps)
+  (should (hash-table-p (clj-edn-read-str "{ }")))
+  (should (hash-table-p (clj-edn-read-str "{}")))
+  (should (map-equal (make-seeded-hash-table :foo :bar :baz :qux)
+                     (clj-edn-read-str "{ :foo :bar :baz :qux}")))
+  (should (map-equal (make-seeded-hash-table 1 "123" 'vector [1 2 3])
+                     (clj-edn-read-str "{ 1 \"123\" vector [1 2 3]}")))
+  (should (map-equal (make-seeded-hash-table [1 2 3] "some numbers")
+                     (clj-edn-read-str "{[1 2 3] \"some numbers\"}"))))
+
+(ert-deftest sets ()
+  :tags '(edn sets)
+  (should (eq 'edn-set (car (clj-edn-read-str "#{}"))))
+  (should (eq 'edn-set (car (clj-edn-read-str "#{ }"))))
+  (should (equal '(edn-set (1 2 3)) (clj-edn-read-str "#{1 2 3}")))
+  (should (equal '(edn-set (1 [1 2 3] 3)) (clj-edn-read-str "#{1 [1 2 3] 
3}"))))
+
+(ert-deftest comment ()
+  :tags '(edn comments)
+  (should-not (clj-edn-read-str ";nada"))
+  (should (equal 1 (clj-edn-read-str ";; comment
+1")))
+  (should (equal [1 2 3] (clj-edn-read-str "[1 2 ;comment to eol
+3]")))
+  (should (equal '[valid more items] (clj-edn-read-str "[valid;touching 
trailing comment
+ more items]")))
+  (should (equal [valid vector more vector items] (clj-edn-read-str "[valid 
vector
+ ;;comment in vector
+ more vector items]"))))
+
+(defun test-val-passed-to-handler (val)
+  (should (listp val))
+  (should (= (length val) 2))
+  (should (= 1 (car val)))
+  1)
+
+(setq clj-edn-test-extra-handlers
+      (a-list
+       'my/type #'test-val-passed-to-handler
+       'my/other-type (lambda (val) 2)))
+
+(ert-deftest tags ()
+  :tags '(edn tags)
+  (should-error (clj-edn-read-str "#my/type value" 
clj-edn-test-extra-handlers))
+  (should (= 1 (clj-edn-read-str "#my/type (1 2)" 
clj-edn-test-extra-handlers)))
+  (should (= 2 (clj-edn-read-str "#my/other-type {:foo :bar}" 
clj-edn-test-extra-handlers)))
+  (should-error (clj-edn-read-str "#myapp/Person {:first \"Fred\" :last 
\"Mertz\"}")))
+
+(ert-deftest roundtrip ()
+  :tags '(edn roundtrip)
+  (let ((data [1 2 3 :foo (4 5) qux "quux"]))
+    (should (equal data (clj-edn-read-str (clj-edn-print-str data))))
+    (should (map-equal (make-seeded-hash-table :foo :bar)
+                       (clj-edn-read-str (clj-edn-print-str 
(make-seeded-hash-table :foo :bar)))))
+    (should (equal '(edn-set (1 2 3 [3 1.11]))
+                   (clj-edn-read-str (clj-edn-print-str '(edn-set (1 2 3 [3 
1.11]))))))))
+
+(ert-deftest inst ()
+  :tags '(edn inst)
+  (let* ((inst-str "#inst \"1985-04-12T23:20:50.52Z\"")
+         (inst (clj-edn-read-str inst-str))
+         (time (date-to-time "1985-04-12T23:20:50.52Z")))
+    (should (eq 'edn-inst (car inst)))
+    (should (equal time (cdr inst)))))
+
+(ert-deftest uuid ()
+  :tags '(edn uuid)
+  (let* ((str "f81d4fae-7dec-11d0-a765-00a0c91e6bf6")
+         (uuid (clj-edn-read-str (concat "#uuid \"" str "\""))))
+    (should (eq 'edn-uuid (car uuid)))))
+
+;; (ert-deftest invalid-edn ()
+;;   (should-error (clj-edn-read-str "///"))
+;;   (should-error (clj-edn-read-str "~cat"))
+;;   (should-error (clj-edn-read-str "foo/bar/baz/qux/quux"))
+;;   (should-error (clj-edn-read-str "#foo/"))
+;;   (should-error (clj-edn-read-str "foo/"))
+;;   (should-error (clj-edn-read-str ":foo/"))
+;;   (should-error (clj-edn-read-str "#/foo"))
+;;   (should-error (clj-edn-read-str "/symbol"))
+;;   (should-error (clj-edn-read-str ":/foo"))
+;;   (should-error (clj-edn-read-str "+5symbol"))
+;;   (should-error (clj-edn-read-str ".\\newline"))
+;;   (should-error (clj-edn-read-str "0cat"))
+;;   (should-error (clj-edn-read-str "-4cats"))
+;;   (should-error (clj-edn-read-str ".9"))
+;;   (should-error (clj-edn-read-str ":keyword/with/too/many/slashes"))
+;;   (should-error (clj-edn-read-str ":a.b.c/"))
+;;   (should-error (clj-edn-read-str "\\itstoolong"))
+;;   (should-error (clj-edn-read-str ":#/:"))
+;;   (should-error (clj-edn-read-str "/foo//"))
+;;   (should-error (clj-edn-read-str "///foo"))
+;;   (should-error (clj-edn-read-str ":{}"))
+;;   (should-error (clj-edn-read-str "//"))
+;;   (should-error (clj-edn-read-str "##"))
+;;   (should-error (clj-edn-read-str "::"))
+;;   (should-error (clj-edn-read-str "::a"))
+;;   (should-error (clj-edn-read-str ".5symbol"))
+;;   (should-error (clj-edn-read-str "{ \"foo\""))
+;;   (should-error (clj-edn-read-str "{ \"foo\" :bar"))
+;;   (should-error (clj-edn-read-str "{"))
+;;   (should-error (clj-edn-read-str ":{"))
+;;   (should-error (clj-edn-read-str "{{"))
+;;   (should-error (clj-edn-read-str "}"))
+;;   (should-error (clj-edn-read-str ":}"))
+;;   (should-error (clj-edn-read-str "}}"))
+;;   (should-error (clj-edn-read-str "#:foo"))
+;;   (should-error (clj-edn-read-str "\\newline."))
+;;   (should-error (clj-edn-read-str "\\newline0.1"))
+;;   (should-error (clj-edn-read-str "^"))
+;;   (should-error (clj-edn-read-str ":^"))
+;;   (should-error (clj-edn-read-str "_:^"))
+;;   (should-error (clj-edn-read-str "#{{[}}"))
+;;   (should-error (clj-edn-read-str "[}"))
+;;   (should-error (clj-edn-read-str "@cat")))
+
+;;; edn-el-parity-test.el ends here
diff --git a/test/clj-edn-test.el b/test/clj-edn-test.el
new file mode 100644
index 0000000000..310b1324fa
--- /dev/null
+++ b/test/clj-edn-test.el
@@ -0,0 +1,77 @@
+;;; clj-edn-test.el --- Unit tests for EDN reading/printing
+
+;; Copyright (C) 2017  Arne Brasseur
+
+;; Author: Arne Brasseur <arne@arnebrasseur.net>
+
+;; This file is not part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary
+
+;; Unit tests for EDN reading/printing
+
+;;; Code
+
+(require 'ert)
+(require 'clj-parse)
+
+(load "test/clj-parse-test-data.el")
+
+(ert-deftest clj-edn-print-test ()
+  (should (equal (clj-edn-print-str nil) "nil"))
+  (should (equal (clj-edn-print-str 100) "100"))
+  (should (equal (clj-edn-print-str 1.2) "1.2"))
+  (should (equal (clj-edn-print-str [1 2 3]) "[1 2 3]"))
+  (should (equal (clj-edn-print-str t) "true")))
+
+(ert-deftest clj-edn-read-test ()
+  (should (equal (clj-edn-read-str "true") t)))
+
+(defmacro define-clj-edn-read-tests ()
+  `(progn
+     ,@(mapcar
+        (lambda (pair)
+          (let ((name (car pair))
+                (data (cdr pair)))
+            (if (and (a-get data :edn) (a-get data :source))
+                (let ((test-name (intern (concat "clj-edn-read:" name))))
+                  `(ert-deftest ,test-name ()
+                     :tags '(clj-edn)
+                     (with-temp-buffer
+                       (insert ,(a-get data :source))
+                       (goto-char 1)
+                       (should (a-equal (clj-edn-read) ',(a-get data 
:edn)))))))))
+        clj-parse-test-data)))
+
+(defmacro define-clj-edn-roundtrip-tests ()
+  `(progn
+     ,@(mapcar
+        (lambda (pair)
+          (let ((name (car pair))
+                (data (cdr pair)))
+            (if (and (a-get data :edn) (a-get data :source) (member 
:edn-roundtrip (a-get data :tags)))
+                (let ((test-name (intern (concat "clj-edn-rountrip:" name))))
+                  `(ert-deftest ,test-name ()
+                     :tags '(clj-edn-rountrip)
+                     (should (equal (clj-edn-print-str (car ',(a-get data 
:edn))) ,(a-get data :source))))))))
+        clj-parse-test-data)))
+
+(define-clj-edn-read-tests)
+(define-clj-edn-roundtrip-tests)
+
+;;; clj-edn-test.el
diff --git a/tests/clj-lex-test.el b/test/clj-lex-test.el
similarity index 99%
rename from tests/clj-lex-test.el
rename to test/clj-lex-test.el
index b50de580f2..ae8325b741 100644
--- a/tests/clj-lex-test.el
+++ b/test/clj-lex-test.el
@@ -1,4 +1,4 @@
-;;; clj-lex-test.el --- Clojure/EDN parser
+;;; clj-lex-test.el --- Unit tests for the lexer
 
 ;; Copyright (C) 2017  Arne Brasseur
 
@@ -21,8 +21,14 @@
 ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 ;; Boston, MA 02110-1301, USA.
 
-(require 'clj-lex)
+;;; Commentary
+
+;; Unit tests for the lexer
+
+;;; Code
+
 (require 'ert)
+(require 'clj-lex)
 
 (ert-deftest clj-lex-test-next ()
   (with-temp-buffer
diff --git a/test/clj-parse-test-data.el b/test/clj-parse-test-data.el
new file mode 100644
index 0000000000..d6f5645d9d
--- /dev/null
+++ b/test/clj-parse-test-data.el
@@ -0,0 +1,298 @@
+;;; clj-parse-test-data.el --- Clojure/EDN parser - test data
+
+;; Copyright (C) 2017  Arne Brasseur
+
+;; Author: Arne Brasseur <arne@arnebrasseur.net>
+
+;; This file is not part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; Test data for reader / parser / printer / unparser
+
+;;; Code:
+
+(setq clj-parse-test-data
+  (a-list
+
+   "simple-list"
+   (a-list
+    :tags '(:edn-roundtrip)
+    :source "(1 2 3)"
+    :edn '((1 2 3))
+    :ast '((:node-type . :root)
+           (:position . 0)
+           (:children . (((:node-type . :list)
+                          (:position . 1)
+                          (:children . (((:node-type . :number)
+                                         (:position . 2)
+                                         (:form . "1")
+                                         (:value . 1))
+                                        ((:node-type . :number)
+                                         (:position . 4)
+                                         (:form . "2")
+                                         (:value . 2))
+                                        ((:node-type . :number)
+                                         (:position . 6)
+                                         (:form . "3")
+                                         (:value . 3)))))))))
+
+
+   "empty-list"
+   (a-list
+    :source "()"
+    :edn '(())
+    :ast '((:node-type . :root)
+           (:position . 0)
+           (:children . (((:node-type . :list)
+                          (:position . 1)
+                          (:children . nil))))))
+
+   "size-1"
+   (a-list
+    :tags '(:edn-roundtrip)
+    :source "(1)"
+    :edn '((1))
+    :ast '((:node-type . :root)
+           (:position . 0)
+           (:children . (((:node-type . :list)
+                          (:position . 1)
+                          (:children . (((:node-type . :number)
+                                         (:position . 2)
+                                         (:form . "1")
+                                         (:value . 1)))))))))
+
+   "leafs"
+   (a-list
+    :source "(nil true false hello-world)"
+    :edn '((nil t nil hello-world))
+    :ast '((:node-type . :root)
+           (:position . 0)
+           (:children . (((:node-type . :list)
+                          (:position . 1)
+                          (:children . (((:node-type . :nil)
+                                         (:position . 2)
+                                         (:form . "nil")
+                                         (:value . nil))
+                                        ((:node-type . :true)
+                                         (:position . 6)
+                                         (:form . "true")
+                                         (:value . t))
+                                        ((:node-type . :false)
+                                         (:position . 11)
+                                         (:form . "false")
+                                         (:value . nil))
+                                        ((:node-type . :symbol)
+                                         (:position . 17)
+                                         (:form . "hello-world")
+                                         (:value . hello-world)))))))))
+
+   "qualified-symbol"
+   (a-list
+    :tags '(:edn-roundtrip)
+    :source "clojure.string/join"
+    :edn '(clojure.string/join)
+    :ast '((:node-type . :root)
+           (:position . 0)
+           (:children . (((:node-type . :symbol)
+                          (:position . 1)
+                          (:form . "clojure.string/join")
+                          (:value . clojure.string/join))))))
+
+   "nested-lists"
+   (a-list
+    :source "((.9 abc (true) (hello)))"
+    :edn '(((0.9 abc (t) (hello))))
+    :ast '((:node-type . :root)
+           (:position . 0)
+           (:children . (((:node-type . :list)
+                          (:position . 1)
+                          (:children . (((:node-type . :list)
+                                         (:position . 2)
+                                         (:children ((:node-type . :number)
+                                                     (:position . 3)
+                                                     (:form . ".9")
+                                                     (:value . 0.9))
+                                                    ((:node-type . :symbol)
+                                                     (:position . 6)
+                                                     (:form . "abc")
+                                                     (:value . abc))
+                                                    ((:node-type . :list)
+                                                     (:position . 10)
+                                                     (:children ((:node-type . 
:true)
+                                                                 (:position . 
11)
+                                                                 (:form . 
"true")
+                                                                 (:value . 
t))))
+                                                    ((:node-type . :list)
+                                                     (:position . 17)
+                                                     (:children ((:node-type . 
:symbol)
+                                                                 (:position . 
18)
+                                                                 (:form . 
"hello")
+                                                                 (:value . 
hello)))))))))))))
+
+   "strings-1"
+   (a-list
+    :tags '(:edn-roundtrip)
+    :source "\"abc hello \\t\\\"x\""
+    :edn '("abc hello \t\"x")
+    :ast '((:node-type . :root)
+           (:position . 0)
+           (:children . (((:node-type . :string)
+                          (:position . 1)
+                          (:form . "\"abc hello \\t\\\"x\"")
+                          (:value . "abc hello \t\"x"))))))
+
+   "strings-2"
+   (a-list
+    :source "(\"---\\f---\\\"-'\\'-\\\\-\\r\\n\")"
+    :edn '(("---\f---\"-''-\\-\r\n"))
+    :ast '((:node-type . :root)
+           (:position . 0)
+           (:children . (((:node-type . :list)
+                          (:position . 1)
+                          (:children . (((:node-type . :string)
+                                         (:position . 2)
+                                         (:form . 
"\"---\\f---\\\"-'\\'-\\\\-\\r\\n\"")
+                                         (:value . 
"---\f---\"-''-\\-\r\n")))))))))
+
+   "chars-1"
+   (a-list
+    :source "(\\newline \\return \\space \\tab \\a \\b \\c \\u0078 \\o171)"
+    :edn '((?\n ?\r ?\ ?\t ?a ?b ?c ?x ?y))
+    :ast '((:node-type . :root)
+           (:position . 0)
+           (:children . (((:node-type . :list)
+                          (:position . 1)
+                          (:children . (((:node-type . :character) (:position 
. 2) (:form . "\\newline") (:value . ?\n))
+                                        ((:node-type . :character) (:position 
. 11) (:form . "\\return") (:value . ?\r))
+                                        ((:node-type . :character) (:position 
. 19) (:form . "\\space") (:value . 32))
+                                        ((:node-type . :character) (:position 
. 26) (:form . "\\tab") (:value . ?\t))
+                                        ((:node-type . :character) (:position 
. 31) (:form . "\\a") (:value . ?a))
+                                        ((:node-type . :character) (:position 
. 34) (:form . "\\b") (:value . ?b))
+                                        ((:node-type . :character) (:position 
. 37) (:form . "\\c") (:value . ?c))
+                                        ((:node-type . :character) (:position 
. 40) (:form . "\\u0078") (:value . ?x))
+                                        ((:node-type . :character) (:position 
. 47) (:form . "\\o171") (:value . ?y)))))))))
+
+   "chars-2"
+   (a-list
+    :source "\"\\u0078 \\o171\""
+    :edn '("x y")
+    :ast '((:node-type . :root)
+           (:position . 0)
+           (:children . (((:node-type . :string)
+                          (:position . 1)
+                          (:form . "\"\\u0078 \\o171\"")
+                          (:value . "x y"))))))
+
+   "keywords"
+   (a-list
+    :tags '(:edn-roundtrip)
+    :source ":foo-bar"
+    :edn '(:foo-bar)
+    :ast '((:node-type . :root)
+           (:position . 0)
+           (:children . (((:node-type . :keyword)
+                          (:position . 1)
+                          (:form . ":foo-bar")
+                          (:value . :foo-bar))))))
+
+   "vector"
+   (a-list
+    :tags '(:edn-roundtrip)
+    :source "[123]"
+    :edn '([123])
+    :ast '((:node-type . :root)
+           (:position . 0)
+           (:children . (((:node-type . :vector)
+                          (:position . 1)
+                          (:children . (((:node-type . :number)
+                                         (:position . 2)
+                                         (:form . "123")
+                                         (:value . 123)))))))))
+
+   "map"
+   (a-list
+    :tags '(:edn-roundtrip)
+    :source "{:count 123}"
+    :edn (list (a-hash-table :count 123))
+    :ast '((:node-type . :root)
+           (:position . 0)
+           (:children . (((:node-type . :map)
+                          (:position . 1)
+                          (:children . (((:node-type . :keyword)
+                                         (:position . 2)
+                                         (:form . ":count")
+                                         (:value . :count))
+                                        ((:node-type . :number)
+                                         (:position . 9)
+                                         (:form . "123")
+                                         (:value . 123)))))))))
+
+   "set"
+   (a-list
+    :tags '(:edn-roundtrip)
+    :source "#{:x}"
+    :edn '((edn-set (:x)))
+    :ast '((:node-type . :root)
+           (:position . 0)
+           (:children . (((:node-type . :set)
+                          (:position . 1)
+                          (:children . (((:node-type . :keyword)
+                                         (:position . 3)
+                                         (:form . ":x")
+                                         (:value . :x)))))))))
+
+   "discard"
+   (a-list
+    :source "(10 #_11 12 #_#_ 13 14)"
+    :edn '((10 12))
+    :ast '((:node-type . :root)
+           (:position . 0)
+           (:children . (((:node-type . :list)
+                          (:position . 1)
+                          (:children . (((:node-type . :number)
+                                         (:position . 2)
+                                         (:form . "10")
+                                         (:value . 10))
+                                        ((:node-type . :number)
+                                         (:position . 10)
+                                         (:form . "12")
+                                         (:value . 12)))))))))
+
+
+   "tag"
+   (a-list
+    :source "#foo/bar [1]"
+    :ast '((:node-type . :root)
+           (:position . 0)
+           (:children . (((:node-type . :tag)
+                          (:position . 1)
+                          (:tag . foo/bar)
+                          (:children . (((:node-type . :vector)
+                                         (:position . 10)
+                                         (:children . (((:node-type . :number)
+                                                        (:position . 11)
+                                                        (:form . "1")
+                                                        (:value . 1))))))))))))
+
+   "booleans"
+   (a-list
+    :source "[nil true false]"
+    :edn '([nil t nil]))))
+
+;;; clj-parse-test-data.el ends here
diff --git a/test/clj-parse-test.el b/test/clj-parse-test.el
new file mode 100644
index 0000000000..172664cfb1
--- /dev/null
+++ b/test/clj-parse-test.el
@@ -0,0 +1,38 @@
+;;; clj-parse-test.el --- Clojure/EDN parser - tests
+
+;; Copyright (C) 2017  Arne Brasseur
+
+;; Author: Arne Brasseur <arne@arnebrasseur.net>
+
+;; This file is not part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; A reader for EDN data files and parser for Clojure source files - tests
+
+;;; Code:
+
+(require 'ert)
+(require 'clj-parse)
+
+;; needs testing of individual functions. all testing now is at the top level
+;; through parse/unparse
+
+(provide 'clj-parse-test)
+
+;;; clj-parse-test.el ends here
diff --git a/test/test-helper.el b/test/test-helper.el
new file mode 100644
index 0000000000..ebc4a58ac2
--- /dev/null
+++ b/test/test-helper.el
@@ -0,0 +1,38 @@
+;;; test-helper.el --- unit test helper functions -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017  Arne Brasseur
+
+;; Author: Arne Brasseur <arne@arnebrasseur.net>
+
+;; This file is not part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; Unit Test setup and helper functions
+
+;;; Code:
+
+(message "Running tests on Emacs %s" emacs-version)
+
+(let* ((current-file (if load-in-progress load-file-name (buffer-file-name)))
+       (source-directory (locate-dominating-file current-file "Cask"))
+       ;; Do not load outdated byte code for tests
+       (load-prefer-newer t))
+  (add-to-list 'load-path source-directory))
+
+;; test-helper.el ends here
diff --git a/tests/clj-parse-test.el b/tests/clj-parse-test.el
deleted file mode 100644
index 726740b545..0000000000
--- a/tests/clj-parse-test.el
+++ /dev/null
@@ -1,404 +0,0 @@
-;;; clj-parse-test.el --- Clojure/EDN parser
-
-;; Copyright (C) 2017  Arne Brasseur
-
-;; Author: Arne Brasseur <arne@arnebrasseur.net>
-
-;; This file is not part of GNU Emacs.
-
-;; This file is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
-
-;; This file is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to
-;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
-
-;;; Commentary:
-
-;; A reader for EDN data files and parser for Clojure source files.
-
-;;; Code:
-
-(require 'a)
-(require 'ert)
-(require 'clj-parse)
-
-(defun clj-parse--equal (a b)
-  (cond
-   ((and (hash-table-p a) (hash-table-p b))
-    (a-equal a b))
-   ((and (consp a) (consp b))
-    (and (clj-parse--equal (car a) (car b))
-         (clj-parse--equal (cdr a) (cdr b))))
-   (t (equal a b))))
-
-(defun clj-parse--deftest-mode (mode test-name test-string expected)
-  (let* ((parse-fn (intern (concat "clj-parse-" mode)))
-         (test-name (intern (concat (symbol-name parse-fn) "-" (symbol-name 
test-name)))))
-    `(ert-deftest ,test-name ()
-       (with-temp-buffer
-         (insert ,test-string)
-         (goto-char 1)
-         (should (clj-parse--equal (,parse-fn) ,expected))))))
-
-(defmacro clj-parse-deftest (test-name test-string mode-vs-expected-alist)
-  (declare (indent defun))
-  `(progn
-     ,@(mapcar (lambda (vs) (clj-parse--deftest-mode (car vs)
-                                                     test-name
-                                                     test-string
-                                                     (cadr vs)))
-               mode-vs-expected-alist)))
-
-
-;;; Parser modes
-;; ----------------------------------------------------------------------------
-
-(clj-parse-deftest simple-list "(1 2 3)"
-  (("edn" '((1 2 3)))
-   ("ast" '((:node-type . :root)
-            (:position . 0)
-            (:children . (((:node-type . :list)
-                           (:position . 1)
-                           (:children . (((:node-type . :number)
-                                          (:position . 2)
-                                          (:form . "1")
-                                          (:value . 1))
-                                         ((:node-type . :number)
-                                          (:position . 4)
-                                          (:form . "2")
-                                          (:value . 2))
-                                         ((:node-type . :number)
-                                          (:position . 6)
-                                          (:form . "3")
-                                          (:value . 3)))))))))))
-
-
-(clj-parse-deftest empty-list "()"
-  (("edn" '(()))
-   ("ast" '((:node-type . :root)
-            (:position . 0)
-            (:children . (((:node-type . :list)
-                           (:position . 1)
-                           (:children . nil))))))))
-
-(clj-parse-deftest size-1 "(1)"
-  (("edn" '((1)))
-   ("ast" '((:node-type . :root)
-            (:position . 0)
-            (:children . (((:node-type . :list)
-                           (:position . 1)
-                           (:children . (((:node-type . :number)
-                                          (:position . 2)
-                                          (:form . "1")
-                                          (:value . 1)))))))))))
-
-(clj-parse-deftest leafs "(nil true false hello-world)"
-  (("edn" '((nil t nil hello-world)))
-   ("ast" '((:node-type . :root)
-            (:position . 0)
-            (:children . (((:node-type . :list)
-                           (:position . 1)
-                           (:children . (((:node-type . :nil)
-                                          (:position . 2)
-                                          (:form . "nil")
-                                          (:value . nil))
-                                         ((:node-type . :true)
-                                          (:position . 6)
-                                          (:form . "true")
-                                          (:value . t))
-                                         ((:node-type . :false)
-                                          (:position . 11)
-                                          (:form . "false")
-                                          (:value . nil))
-                                         ((:node-type . :symbol)
-                                          (:position . 17)
-                                          (:form . "hello-world")
-                                          (:value . hello-world)))))))))))
-
-(clj-parse-deftest qualified-symbol "clojure.string/join"
-  (("edn" '(clojure.string/join))
-   ("ast" '((:node-type . :root)
-            (:position . 0)
-            (:children . (((:node-type . :symbol)
-                           (:position . 1)
-                           (:form . "clojure.string/join")
-                           (:value . clojure.string/join))))))))
-
-(clj-parse-deftest nested-lists "((.9 abc (true) (hello)))"
-  (("edn" '(((0.9 abc (t) (hello)))))
-   ("ast" '((:node-type . :root)
-            (:position . 0)
-            (:children . (((:node-type . :list)
-                           (:position . 1)
-                           (:children . (((:node-type . :list)
-                                          (:position . 2)
-                                          (:children ((:node-type . :number)
-                                                      (:position . 3)
-                                                      (:form . ".9")
-                                                      (:value . 0.9))
-                                                     ((:node-type . :symbol)
-                                                      (:position . 6)
-                                                      (:form . "abc")
-                                                      (:value . abc))
-                                                     ((:node-type . :list)
-                                                      (:position . 10)
-                                                      (:children ((:node-type 
. :true)
-                                                                  (:position . 
11)
-                                                                  (:form . 
"true")
-                                                                  (:value . 
t))))
-                                                     ((:node-type . :list)
-                                                      (:position . 17)
-                                                      (:children ((:node-type 
. :symbol)
-                                                                  (:position . 
18)
-                                                                  (:form . 
"hello")
-                                                                  (:value . 
hello)))))))))))))))
-
-(clj-parse-deftest strings-1 "\"abc hello \\t\\\"x\""
-  (("edn" '("abc hello \t\"x"))
-   ("ast" '((:node-type . :root)
-            (:position . 0)
-            (:children . (((:node-type . :string)
-                           (:position . 1)
-                           (:form . "\"abc hello \\t\\\"x\"")
-                           (:value . "abc hello \t\"x"))))))))
-
-(clj-parse-deftest strings-2 "(\"---\\f---\\\"-'\\'-\\\\-\\r\\n\")"
-  (("edn" '(("---\f---\"-''-\\-\r\n")))
-   ("ast" '((:node-type . :root)
-            (:position . 0)
-            (:children . (((:node-type . :list)
-                           (:position . 1)
-                           (:children . (((:node-type . :string)
-                                          (:position . 2)
-                                          (:form . 
"\"---\\f---\\\"-'\\'-\\\\-\\r\\n\"")
-                                          (:value . 
"---\f---\"-''-\\-\r\n")))))))))))
-
-(clj-parse-deftest chars-1 "(\\newline \\return \\space \\tab \\a \\b \\c 
\\u0078 \\o171)"
-  (("edn" '((?\n ?\r ?\ ?\t ?a ?b ?c ?x ?y)))
-   ("ast" '((:node-type . :root)
-            (:position . 0)
-            (:children . (((:node-type . :list)
-                           (:position . 1)
-                           (:children . (((:node-type . :character) (:position 
. 2) (:form . "\\newline") (:value . ?\n))
-                                         ((:node-type . :character) (:position 
. 11) (:form . "\\return") (:value . ?\r))
-                                         ((:node-type . :character) (:position 
. 19) (:form . "\\space") (:value . 32))
-                                         ((:node-type . :character) (:position 
. 26) (:form . "\\tab") (:value . ?\t))
-                                         ((:node-type . :character) (:position 
. 31) (:form . "\\a") (:value . ?a))
-                                         ((:node-type . :character) (:position 
. 34) (:form . "\\b") (:value . ?b))
-                                         ((:node-type . :character) (:position 
. 37) (:form . "\\c") (:value . ?c))
-                                         ((:node-type . :character) (:position 
. 40) (:form . "\\u0078") (:value . ?x))
-                                         ((:node-type . :character) (:position 
. 47) (:form . "\\o171") (:value . ?y)))))))))))
-
-(clj-parse-deftest chars-2 "\"\\u0078 \\o171\""
-  (("edn" '("x y"))
-   ("ast" '((:node-type . :root)
-            (:position . 0)
-            (:children . (((:node-type . :string)
-                           (:position . 1)
-                           (:form . "\"\\u0078 \\o171\"")
-                           (:value . "x y"))))))))
-
-(clj-parse-deftest keywords ":foo-bar"
-  (("edn" '(:foo-bar))
-   ("ast" '((:node-type . :root)
-            (:position . 0)
-            (:children . (((:node-type . :keyword)
-                           (:position . 1)
-                           (:form . ":foo-bar")
-                           (:value . :foo-bar))))))))
-
-(clj-parse-deftest vector "[123]"
-  (("edn" '([123]))
-   ("ast" '((:node-type . :root)
-            (:position . 0)
-            (:children . (((:node-type . :vector)
-                           (:position . 1)
-                           (:children . (((:node-type . :number)
-                                          (:position . 2)
-                                          (:form . "123")
-                                          (:value . 123)))))))))))
-
-(clj-parse-deftest map "{:count 123}"
-  (("edn" (list (a-hash-table :count 123)))
-   ("ast" '((:node-type . :root)
-            (:position . 0)
-            (:children . (((:node-type . :map)
-                           (:position . 1)
-                           (:children . (((:node-type . :keyword)
-                                          (:position . 2)
-                                          (:form . ":count")
-                                          (:value . :count))
-                                         ((:node-type . :number)
-                                          (:position . 9)
-                                          (:form . "123")
-                                          (:value . 123)))))))))))
-
-(clj-parse-deftest set "#{:x}"
-  (("edn" '((edn-set (:x))))
-   ("ast" '((:node-type . :root)
-            (:position . 0)
-            (:children . (((:node-type . :set)
-                           (:position . 1)
-                           (:children . (((:node-type . :keyword)
-                                          (:position . 3)
-                                          (:form . ":x")
-                                          (:value . :x)))))))))))
-
-(clj-parse-deftest discard "(10 #_11 12 #_#_ 13 14)"
-  (("edn" '((10 12)))
-   ("ast" '((:node-type . :root)
-            (:position . 0)
-            (:children . (((:node-type . :list)
-                           (:position . 1)
-                           (:children . (((:node-type . :number)
-                                          (:position . 2)
-                                          (:form . "10")
-                                          (:value . 10))
-                                         ((:node-type . :number)
-                                          (:position . 10)
-                                          (:form . "12")
-                                          (:value . 12)))))))))))
-
-
-;;; Printer modes
-;; ----------------------------------------------------------------------------
-
-(ert-deftest clj-parse-ast-print-list ()
-  (should (equal "(0 1 2)"
-                 (clj-parse-ast-print '((:node-type . :root)
-                                        (:position . 0)
-                                        (:children . (((:node-type . :list)
-                                                       (:position . 1)
-                                                       (:children . 
(((:node-type . :number)
-                                                                      
(:position . 2)
-                                                                      (:form . 
"0")
-                                                                      (:value 
. 0))
-                                                                     
((:node-type . :number)
-                                                                      
(:position . 4)
-                                                                      (:form . 
"1")
-                                                                      (:value 
. 1))
-                                                                     
((:node-type . :number)
-                                                                      
(:position . 6)
-                                                                      (:form . 
"2")
-                                                                      (:value 
. 2))))))))))))
-
-(ert-deftest clj-parse-ast-print-empty-list ()
-  (should (equal "()"
-                 (clj-parse-ast-print '((:node-type . :root)
-                                        (:position . 0)
-                                        (:children . (((:node-type . :list)
-                                                       (:position . 1)
-                                                       (:children . 
nil)))))))))
-
-(ert-deftest clj-parse-ast-print-nested-list ()
-  (should (equal "((.9 abc (true) (hello)))"
-                 (clj-parse-ast-print '((:node-type . :root)
-                                        (:position . 0)
-                                        (:children . (((:node-type . :list)
-                                                       (:position . 1)
-                                                       (:children . 
(((:node-type . :list)
-                                                                      
(:position . 2)
-                                                                      
(:children ((:node-type . :number)
-                                                                               
   (:position . 3)
-                                                                               
   (:form . ".9")
-                                                                               
   (:value . 0.9))
-                                                                               
  ((:node-type . :symbol)
-                                                                               
   (:position . 6)
-                                                                               
   (:form . "abc")
-                                                                               
   (:value . abc))
-                                                                               
  ((:node-type . :list)
-                                                                               
   (:position . 10)
-                                                                               
   (:children ((:node-type . :true)
-                                                                               
               (:position . 11)
-                                                                               
               (:form . "true")
-                                                                               
               (:value . t))))
-                                                                               
  ((:node-type . :list)
-                                                                               
   (:position . 17)
-                                                                               
   (:children ((:node-type . :symbol)
-                                                                               
               (:position . 18)
-                                                                               
               (:form . "hello")
-                                                                               
               (:value . hello))))))))))))))))
-
-(ert-deftest clj-parse-ast-print-string ()
-  (should (equal "\"abc hello \\t\\\"x\""
-                 (clj-parse-ast-print '((:node-type . :root)
-                                        (:position . 0)
-                                        (:children . (((:node-type . :string)
-                                                       (:position . 1)
-                                                       (:form . "\"abc hello 
\\t\\\"x\"")
-                                                       (:value . "abc hello 
\t\"x")))))))))
-
-(ert-deftest clj-parse-ast-print-chars ()
-  (should (equal "(\\newline \\return \\space \\tab \\a \\b \\c \\u0078 
\\o171)"
-                 (clj-parse-ast-print '((:node-type . :root)
-                                        (:position . 0)
-                                        (:children . (((:node-type . :list)
-                                                       (:position . 1)
-                                                       (:children . 
(((:node-type . :character) (:position . 2) (:form . "\\newline") (:value . 
?\n))
-                                                                     
((:node-type . :character) (:position . 11) (:form . "\\return") (:value . ?\r))
-                                                                     
((:node-type . :character) (:position . 19) (:form . "\\space") (:value . 32))
-                                                                     
((:node-type . :character) (:position . 26) (:form . "\\tab") (:value . ?\t))
-                                                                     
((:node-type . :character) (:position . 31) (:form . "\\a") (:value . ?a))
-                                                                     
((:node-type . :character) (:position . 34) (:form . "\\b") (:value . ?b))
-                                                                     
((:node-type . :character) (:position . 37) (:form . "\\c") (:value . ?c))
-                                                                     
((:node-type . :character) (:position . 40) (:form . "\\u0078") (:value . ?x))
-                                                                     
((:node-type . :character) (:position . 47) (:form . "\\o171") (:value . 
?y))))))))))))
-
-(ert-deftest clj-parse-ast-print-keyword ()
-  (should (equal ":foo-bar"
-                 (clj-parse-ast-print '((:node-type . :root)
-                                        (:position . 0)
-                                        (:children . (((:node-type . :keyword)
-                                                       (:position . 1)
-                                                       (:form . ":foo-bar")
-                                                       (:value . 
:foo-bar)))))))))
-
-(ert-deftest clj-parse-ast-print-vector ()
-  (should (equal "[123]"
-                 (clj-parse-ast-print '((:node-type . :root)
-                                        (:position . 0)
-                                        (:children . (((:node-type . :vector)
-                                                       (:position . 1)
-                                                       (:children . 
(((:node-type . :number)
-                                                                      
(:position . 2)
-                                                                      (:form . 
"123")
-                                                                      (:value 
. 123))))))))))))
-
-(ert-deftest clj-parse-ast-print-map ()
-  (should (equal "{:count 123}"
-                 (clj-parse-ast-print '((:node-type . :root)
-                                        (:position . 0)
-                                        (:children . (((:node-type . :map)
-                                                       (:position . 1)
-                                                       (:children . 
(((:node-type . :keyword)
-                                                                      
(:position . 2)
-                                                                      (:form . 
":count")
-                                                                      (:value 
. :count))
-                                                                     
((:node-type . :number)
-                                                                      
(:position . 9)
-                                                                      (:form . 
"123")
-                                                                      (:value 
. 123))))))))))))
-
-(ert-deftest clj-parse-ast-print-set ()
-  (should (equal "#{:x}"
-                 (clj-parse-ast-print '((:node-type . :root)
-                                        (:position . 0)
-                                        (:children . (((:node-type . :set)
-                                                       (:position . 1)
-                                                       (:children . 
(((:node-type . :keyword)
-                                                                      
(:position . 3)
-                                                                      (:form . 
":x")
-                                                                      (:value 
. :x))))))))))))
-
-(provide 'clj-parse-test)
-
-;;; clj-parse-test.el ends here
diff --git a/tests/edn-el-test-suite.el b/tests/edn-el-test-suite.el
deleted file mode 100644
index f2dc7e387b..0000000000
--- a/tests/edn-el-test-suite.el
+++ /dev/null
@@ -1,281 +0,0 @@
-;;; edn-el-test-suite.el --- Tests from edn.el
-
-;; Author: Lars Andersen <expez@expez.com>, Arne Brasseur 
<arne@arnebrasseur.net>
-
-;; Copyright (C) 2015  Lars Andersen
-
-;; This file is not part of GNU Emacs.
-
-;; This file is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
-
-;; This file is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to
-;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
-
-;;; Code:
-
-(require 'ert)
-(require 'edn)
-
-(ert-deftest whitespace ()
-  (should (null (clj-parse-edn-str "")))
-  (should (null (clj-parse-edn-str " ")))
-  (should (null (clj-parse-edn-str "   ")))
-  (should (null (clj-parse-edn-str "   ")))
-  (should (null (clj-parse-edn-str "           ")))
-  (should (null (clj-parse-edn-str ",")))
-  (should (null (clj-parse-edn-str ",,,,")))
-  (should (null (clj-parse-edn-str "     , ,
-")))
-  (should (null (clj-parse-edn-str"
-  ,,   ")))
-  (should (equal [a b c d] (clj-parse-edn-str "[a ,,,,,, b,,,,,c ,d]"))))
-
-(ert-deftest symbols ()
-  :tags '(edn symbol)
-  (should (equal 'foo (clj-parse-edn-str "foo")))
-  (should (equal 'foo\. (clj-parse-edn-str "foo.")))
-  (should (equal '%foo\. (clj-parse-edn-str "%foo.")))
-  (should (equal 'foo/bar (clj-parse-edn-str "foo/bar")))
-  (equal 'some\#sort\#of\#symbol (clj-parse-edn-str "some#sort#of#symbol"))
-  (equal 'truefalse (clj-parse-edn-str "truefalse"))
-  (equal 'true. (clj-parse-edn-str "true."))
-  (equal '/ (clj-parse-edn-str "/"))
-  (should (equal '.true (clj-parse-edn-str ".true")))
-  (should (equal 'some:sort:of:symbol (clj-parse-edn-str 
"some:sort:of:symbol")))
-  (equal 'foo-bar (clj-parse-edn-str "foo-bar"))
-  (should (equal '+some-symbol (clj-parse-edn-str "+some-symbol")))
-  (should (equal '-symbol (clj-parse-edn-str "-symbol"))))
-
-(ert-deftest booleans ()
-  :tags '(edn boolean)
-  (should (equal t (clj-parse-edn-str "true")))
-  (should (equal nil (clj-parse-edn-str "false "))))
-
-(ert-deftest characters ()
-  :tags '(edn characters)
-  (should (equal 97 (clj-parse-edn-str "\\a")))
-  (should (equal 960 (clj-parse-edn-str "\\u03C0")))
-  ;;(should (equal 'newline (clj-parse-edn-str "\\newline")))
-  )
-
-(ert-deftest elision ()
-  :tags '(edn elision)
-  (should-not (clj-parse-edn-str "#_foo"))
-  (should-not (clj-parse-edn-str "#_ 123"))
-  (should-not (clj-parse-edn-str "#_:foo"))
-  (should-not (clj-parse-edn-str "#_ \\a"))
-  (should-not (clj-parse-edn-str "#_
-\"foo\""))
-  (should-not (clj-parse-edn-str "#_ (1 2 3)"))
-  (should (equal '(1 3) (clj-parse-edn-str "(1 #_ 2 3)")))
-  (should (equal '[1 2 3 4] (clj-parse-edn-str "[1 2 #_[4 5 6] 3 4]")))
-  (should (map-equal (make-seeded-hash-table :foo :bar)
-                     (clj-parse-edn-str "{:foo #_elided :bar}")))
-  (should (equal (edn-list-to-set '(1 2 3 4))
-                 (clj-parse-edn-str "#{1 2 #_[1 2 3] 3 #_ (1 2) 4}")))
-  (should (equal [a d] (clj-parse-edn-str "[a #_ ;we are discarding what comes 
next
- c d]"))))
-
-(ert-deftest string ()
-  :tags '(edn string)
-  (should (equal "this is a string" (clj-parse-edn-str "\"this is a 
string\"")))
-  (should (equal "this has an escaped \"quote in it"
-                 (clj-parse-edn-str "\"this has an escaped \\\"quote in 
it\"")))
-  (should (equal "foo\tbar" (clj-parse-edn-str "\"foo\\tbar\"")))
-  (should (equal "foo\nbar" (clj-parse-edn-str "\"foo\\nbar\"")))
-  (should (equal "this is a string \\ that has an escaped backslash"
-                 (clj-parse-edn-str "\"this is a string \\\\ that has an 
escaped backslash\"")))
-  (should (equal "[" (clj-parse-edn-str "\"[\""))))
-
-(ert-deftest keywords ()
-  :tags '(edn keywords)
-  (should (equal :namespace\.of\.some\.length/keyword-name
-                 (clj-parse-edn-str ":namespace.of.some.length/keyword-name")))
-  (should (equal :\#/\# (clj-parse-edn-str ":#/#")))
-  (should (equal :\#/:a (clj-parse-edn-str ":#/:a")))
-  (should (equal :\#foo (clj-parse-edn-str ":#foo"))))
-
-(ert-deftest integers ()
-  :tags '(edn integers)
-  (should (= 0 (clj-parse-edn-str "0")))
-  (should (= 0 (clj-parse-edn-str "+0")))
-  (should (= 0 (clj-parse-edn-str "-0")))
-  (should (= 100 (clj-parse-edn-str "100")))
-  (should (= -100 (clj-parse-edn-str "-100"))))
-
-(ert-deftest floats ()
-  :tags '(edn floats)
-  (should (= 12.32 (clj-parse-edn-str "12.32")))
-  (should (= -12.32 (clj-parse-edn-str "-12.32")))
-  (should (= 9923.23 (clj-parse-edn-str "+9923.23")))
-  (should (= 4.5e+044 (clj-parse-edn-str "45e+43")))
-  (should (= -4.5e-042 (clj-parse-edn-str "-45e-43")))
-  (should (= 4.5e+044 (clj-parse-edn-str "45E+43"))))
-
-(ert-deftest lists ()
-  :tags '(edn lists)
-  (should-not (clj-parse-edn-str "()"))
-  (should (equal '(1 2 3) (clj-parse-edn-str "( 1 2 3)")))
-  (should (equal '(12.1 ?a foo :bar) (clj-parse-edn-str "(12.1 \\a foo 
:bar)")))
-  (should (equal '((:foo bar :bar 12)) (clj-parse-edn-str "( (:foo bar :bar 
12))")))
-  (should (equal
-           '(defproject com\.thortech/data\.edn "0.1.0-SNAPSHOT")
-           (clj-parse-edn-str "(defproject com.thortech/data.edn 
\"0.1.0-SNAPSHOT\")"))))
-
-(ert-deftest vectors ()
-  :tags '(edn vectors)
-  (should (equal [] (clj-parse-edn-str "[]")))
-  (should (equal [] (clj-parse-edn-str "[ ]")))
-  (should (equal '[1 2 3] (clj-parse-edn-str "[ 1 2 3 ]")))
-  (should (equal '[12.1 ?a foo :bar] (clj-parse-edn-str "[ 12.1 \\a foo 
:bar]")))
-  (should (equal '[[:foo bar :bar 12]] (clj-parse-edn-str "[[:foo bar :bar 
12]]")))
-  (should (equal '[( :foo bar :bar 12 ) "foo"]
-                 (clj-parse-edn-str "[(:foo bar :bar 12) \"foo\"]")))
-  (should (equal '[/ \. * ! _ \? $ % & = - +]
-                 (clj-parse-edn-str "[/ . * ! _ ? $ % & = - +]")))
-  (should (equal
-           ;;[99 newline return space tab]
-           [99 10 13 32 9]
-           (clj-parse-edn-str "[\\c \\newline \\return \\space \\tab]"))))
-
-(defun map-equal (m1 m2)
-  (and (and (hash-table-p m1) (hash-table-p m2))
-       (eq (hash-table-test m1) (hash-table-test m2))
-       (= (hash-table-count m1) (hash-table-count m2))
-       (equal (hash-table-keys m1) (hash-table-keys m2))
-       (equal (hash-table-values m1) (hash-table-values m2))))
-
-(defun make-seeded-hash-table (&rest keys-and-values)
-  (let ((m (make-hash-table :test #'equal)))
-    (while keys-and-values
-      (puthash (pop keys-and-values) (pop keys-and-values) m))
-    m))
-
-(ert-deftest maps ()
-  :tags '(edn maps)
-  (should (hash-table-p (clj-parse-edn-str "{ }")))
-  (should (hash-table-p (clj-parse-edn-str "{}")))
-  (should (map-equal (make-seeded-hash-table :foo :bar :baz :qux)
-                     (clj-parse-edn-str "{ :foo :bar :baz :qux}")))
-  (should (map-equal (make-seeded-hash-table 1 "123" 'vector [1 2 3])
-                     (clj-parse-edn-str "{ 1 \"123\" vector [1 2 3]}")))
-  (should (map-equal (make-seeded-hash-table [1 2 3] "some numbers")
-                     (clj-parse-edn-str "{[1 2 3] \"some numbers\"}"))))
-
-(ert-deftest sets ()
-  :tags '(edn sets)
-  (should (edn-set-p (clj-parse-edn-str "#{}")))
-  (should (edn-set-p (clj-parse-edn-str "#{ }")))
-  (should (equal (edn-list-to-set '(1 2 3)) (clj-parse-edn-str "#{1 2 3}")))
-  (should (equal (edn-list-to-set '(1 [1 2 3] 3)) (clj-parse-edn-str "#{1 [1 2 
3] 3}"))))
-
-(ert-deftest comment ()
-  :tags '(edn comments)
-  (should-not (clj-parse-edn-str ";nada"))
-  (should (equal 1 (clj-parse-edn-str ";; comment
-1")))
-  (should (equal [1 2 3] (clj-parse-edn-str "[1 2 ;comment to eol
-3]")))
-  (should (equal '[valid more items] (clj-parse-edn-str "[valid;touching 
trailing comment
- more items]")))
-  (should (equal [valid vector more vector items] (clj-parse-edn-str "[valid 
vector
- ;;comment in vector
- more vector items]"))))
-
-(defun test-val-passed-to-handler (val)
-  (should (listp val))
-  (should (= (length val) 2))
-  (should (= 1 (car val)))
-  1)
-
-(setq clj-edn-test-extra-handlers
-      (a-list
-       'my/type #'test-val-passed-to-handler
-       'my/other-type (lambda (val) 2)))
-
-(ert-deftest tags ()
-  :tags '(edn tags)
-  (should-error (clj-parse-edn-str "#my/type value" 
clj-edn-test-extra-handlers))
-  (should (= 1 (clj-parse-edn-str "#my/type (1 2)" 
clj-edn-test-extra-handlers)))
-  (should (= 2 (clj-parse-edn-str "#my/other-type {:foo :bar}" 
clj-edn-test-extra-handlers))))
-
-(ert-deftest roundtrip ()
-  :tags '(edn roundtrip)
-  (let ((data [1 2 3 :foo (4 5) qux "quux"]))
-    (should (equal data (clj-parse-edn-str (edn-print-string data))))
-    (should (map-equal (make-seeded-hash-table :foo :bar)
-                       (clj-parse-edn-str (edn-print-string 
(make-seeded-hash-table :foo :bar)))))
-    (should (equal (edn-list-to-set '(1 2 3 [3 1.11]))
-                   (clj-parse-edn-str (edn-print-string (edn-list-to-set '(1 2 
3 [3 1.11]))))))
-    (should-error (clj-parse-edn-str "#myapp/Person {:first \"Fred\" :last 
\"Mertz\"}"))))
-
-(ert-deftest inst ()
-  :tags '(edn inst)
-  (let* ((inst-str "#inst \"1985-04-12T23:20:50.52Z\"")
-         (inst (clj-parse-edn-str inst-str))
-         (time (date-to-time "1985-04-12T23:20:50.52Z")))
-    (should (edn-inst-p inst))
-    (should (equal time (edn-inst-to-time inst)))))
-
-(ert-deftest uuid ()
-  :tags '(edn uuid)
-  (let* ((str "f81d4fae-7dec-11d0-a765-00a0c91e6bf6")
-         (uuid (clj-parse-edn-str (concat "#uuid \"" str "\""))))
-    (should (edn-uuid-p uuid))))
-
-;; (ert-deftest invalid-edn ()
-;;   (should-error (clj-parse-edn-str "///"))
-;;   (should-error (clj-parse-edn-str "~cat"))
-;;   (should-error (clj-parse-edn-str "foo/bar/baz/qux/quux"))
-;;   (should-error (clj-parse-edn-str "#foo/"))
-;;   (should-error (clj-parse-edn-str "foo/"))
-;;   (should-error (clj-parse-edn-str ":foo/"))
-;;   (should-error (clj-parse-edn-str "#/foo"))
-;;   (should-error (clj-parse-edn-str "/symbol"))
-;;   (should-error (clj-parse-edn-str ":/foo"))
-;;   (should-error (clj-parse-edn-str "+5symbol"))
-;;   (should-error (clj-parse-edn-str ".\\newline"))
-;;   (should-error (clj-parse-edn-str "0cat"))
-;;   (should-error (clj-parse-edn-str "-4cats"))
-;;   (should-error (clj-parse-edn-str ".9"))
-;;   (should-error (clj-parse-edn-str ":keyword/with/too/many/slashes"))
-;;   (should-error (clj-parse-edn-str ":a.b.c/"))
-;;   (should-error (clj-parse-edn-str "\\itstoolong"))
-;;   (should-error (clj-parse-edn-str ":#/:"))
-;;   (should-error (clj-parse-edn-str "/foo//"))
-;;   (should-error (clj-parse-edn-str "///foo"))
-;;   (should-error (clj-parse-edn-str ":{}"))
-;;   (should-error (clj-parse-edn-str "//"))
-;;   (should-error (clj-parse-edn-str "##"))
-;;   (should-error (clj-parse-edn-str "::"))
-;;   (should-error (clj-parse-edn-str "::a"))
-;;   (should-error (clj-parse-edn-str ".5symbol"))
-;;   (should-error (clj-parse-edn-str "{ \"foo\""))
-;;   (should-error (clj-parse-edn-str "{ \"foo\" :bar"))
-;;   (should-error (clj-parse-edn-str "{"))
-;;   (should-error (clj-parse-edn-str ":{"))
-;;   (should-error (clj-parse-edn-str "{{"))
-;;   (should-error (clj-parse-edn-str "}"))
-;;   (should-error (clj-parse-edn-str ":}"))
-;;   (should-error (clj-parse-edn-str "}}"))
-;;   (should-error (clj-parse-edn-str "#:foo"))
-;;   (should-error (clj-parse-edn-str "\\newline."))
-;;   (should-error (clj-parse-edn-str "\\newline0.1"))
-;;   (should-error (clj-parse-edn-str "^"))
-;;   (should-error (clj-parse-edn-str ":^"))
-;;   (should-error (clj-parse-edn-str "_:^"))
-;;   (should-error (clj-parse-edn-str "#{{[}}"))
-;;   (should-error (clj-parse-edn-str "[}"))
-;;   (should-error (clj-parse-edn-str "@cat")))
-
-;;; edn-el-test-suite.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]