source: trunk/abcl/contrib/named-readtables/test/tests.lisp

Last change on this file was 15019, checked in by Mark Evenson, 7 years ago

abcl-contrib: add NAMED-READTABLES

From <https://github.com/melisgl/named-readtables>.

c.f. <https://github.com/melisgl/named-readtables/issues/10>

File size: 9.1 KB
Line 
1;;; -*- Mode:Lisp -*-
2
3(in-package :named-readtables-test)
4
5(defun map-alist (car-fn cdr-fn alist)
6  (mapcar #'(lambda (entry)
7              (cons (funcall car-fn (car entry))
8                    (funcall cdr-fn (cdr entry))))
9          alist))
10
11(defun length=1 (list)
12  (and list (null (cdr list))))
13
14(defmacro signals-condition-p (name &body body)
15  `(handler-case (prog1 nil ,@body)
16     (,(second name) () t)))
17
18(defmacro continue-condition (name &body body)
19  `(handler-bind ((,(second name) #'continue))
20     ,@body))
21
22(defun read-with-readtable (name string)
23  (let ((*package* '#.*package*)
24        (*readtable* (find-readtable name)))
25    (values (read-from-string string))))
26
27(defun random-named-readtable ()
28  (let ((readtables (list-all-named-readtables)))
29    (nth (random (length readtables)) readtables)))
30
31
32(defun readtable-content (named-readtable-designator)
33  (let ((readtable (ensure-readtable named-readtable-designator))
34        (result '()))
35    ;; Make sure to canonicalize the order and function designators so
36    ;; we can compare easily.
37    (do-readtable ((char reader-fn ntp disp? table) readtable)
38      (setq table (sort (copy-list table) #'char< :key #'car))
39      (push (list* char
40                   (ensure-function reader-fn)
41                   ntp
42                   (and disp? (list (map-alist #'identity
43                                               #'ensure-function
44                                               table))))
45            result))
46    (sort result #'char< :key #'car)))
47
48(defun readtable= (rt1 rt2)
49  (tree-equal (readtable-content rt1) (readtable-content rt2)
50              :test #'(lambda (x y)
51                        (if (and (functionp x) (functionp y))
52                            (function= x y)
53                            (eql x y)))))
54
55
56(defun read-A (stream c)
57  (declare (ignore stream c))
58  :a)
59
60(defun read-A-as-X (stream c)
61  (declare (ignore stream c))
62  :x)
63
64(defun read-B (stream c)
65  (declare (ignore stream c))
66  :b)
67
68(defun read-sharp-paren (stream c n)
69  (declare (ignore stream c n))
70  'sharp-paren)
71
72(defun read-C (stream c)
73  (declare (ignore stream c))
74  :c)
75
76(defreadtable A
77  (:macro-char #\A #'read-A))
78
79(defreadtable A-as-X
80  (:macro-char #\A #'read-A-as-X))
81
82(defreadtable A-dispatch
83  (:macro-char #\A :dispatch)
84  (:dispatch-macro-char #\A #\A #'read-A))
85
86(defreadtable A-dispatch-as-X
87  (:macro-char #\A :dispatch)
88  (:dispatch-macro-char #\A #\A #'read-A-as-X))
89
90(defreadtable B
91  (:macro-char #\B #'read-B))
92
93(defreadtable C
94  (:macro-char #\C #'read-C))
95
96(defreadtable A+B+C
97  (:merge A B C))
98
99(defreadtable standard+A+B+C
100  (:merge :standard A+B+C))
101
102(defreadtable sharp-paren
103  (:macro-char #\# :dispatch)
104  (:dispatch-macro-char #\# #\( #'read-sharp-paren))
105
106
107(deftest cruft.1
108    (function= (get-macro-character #\" (copy-readtable nil))
109               (get-macro-character #\" (copy-readtable nil)))
110  t)
111
112(deftest cruft.2
113    (dispatch-macro-char-p #\# (find-readtable :standard))
114  t)
115
116(deftest cruft.3
117    (dispatch-macro-char-p #\# (make-readtable))
118  nil)
119
120(deftest cruft.4
121    (let ((rt (copy-named-readtable :standard)))
122      (ensure-dispatch-macro-character #\# t rt)
123      (dispatch-macro-char-p #\# rt))
124  t)
125
126(deftest cruft.5
127    (let ((rt (make-readtable)))
128      (values
129        (dispatch-macro-char-p #\$ rt)
130        (ensure-dispatch-macro-character #\$ t rt)
131        (dispatch-macro-char-p #\$ rt)))
132  nil t t)
133
134(deftest cruft.6
135    (let ((rt (make-readtable))
136          (fn (constantly nil)))
137      (ensure-dispatch-macro-character #\$ t rt)
138      (set-dispatch-macro-character #\$ #\# fn rt)
139      (values 
140        (eq fn (get-dispatch-macro-character #\$ #\# rt))
141        (length=1 (readtable-content rt))))
142  t t)
143
144(deftest cruft.7
145    (let ((rt (make-readtable))
146          (fn (constantly nil)))
147      (set-macro-character #\$ fn t rt)
148      (values
149        (eq fn (get-macro-character #\$ rt))
150        (length=1 (readtable-content rt))))
151  t t)
152
153
154(deftest standard.1
155    (read-with-readtable :standard "ABC")
156  ABC)
157
158(deftest standard.2
159    (read-with-readtable :standard "(A B C)")
160  (A B C))
161
162(deftest standard.3
163    (let ((x (find-readtable nil))
164          (y (find-readtable :standard))
165          (z (find-readtable :common-lisp)))
166      (and (eq x y) (eq y z)))
167  t)
168
169
170(deftest modern.1
171    (read-with-readtable :modern "FooF")
172  |FooF|)
173
174
175(deftest empty.1
176    (null (readtable-content (make-readtable)))
177  t)
178
179(deftest empty.2
180    (readtable= (merge-readtables-into (make-readtable) :standard)
181                (find-readtable :standard))
182  t)
183
184(deftest empty.3
185    (let ((rt (copy-named-readtable :standard)))
186      (readtable= (merge-readtables-into (make-readtable) rt)
187                  (merge-readtables-into rt (make-readtable))))
188  t)
189
190
191(deftest basics.1
192    (read-with-readtable 'A "A")
193  :a)
194
195(deftest basics.2
196    (read-with-readtable 'A-as-X "A")
197  :x)
198
199(deftest basics.3
200    (read-with-readtable 'A "B")
201  B)
202
203(deftest basics.4
204    (read-with-readtable 'A "(A B C)")
205  |(|)
206
207
208(deftest unregister.1
209    (let ((rt (find-readtable 'A)))
210      (register-readtable 'does-not-exist rt)
211      (values
212        (and (find-readtable 'does-not-exist) t)
213        (unregister-readtable 'does-not-exist)
214        (and (find-readtable 'does-not-exist) t)))
215  t t nil)
216
217
218(deftest name.1
219    (let ((rt (random-named-readtable)))
220      (eq rt (find-readtable (readtable-name rt))))
221  t)
222
223(deftest ensure.1
224    (unwind-protect
225         (let* ((x (ensure-readtable 'does-not-exist (find-readtable 'A)))
226                (y (find-readtable 'A))
227                (z (find-readtable 'does-not-exist)))
228           (and (eq x y) (eq y z)))
229      (unregister-readtable 'does-not-exist))
230  t)
231
232
233(deftest merge.1
234    (values
235      (read-with-readtable 'A+B+C "A")
236      (read-with-readtable 'A+B+C "B")
237      (read-with-readtable 'A+B+C "C"))
238  :a :b :c)
239
240(deftest merge.2
241    (read-with-readtable 'standard+A+B+C "(A B C)")
242  (:a :b :c))
243
244(deftest merge.3
245    (read-with-readtable 'standard+A+B+C "#(A B C)")
246  #(:a :b :c))
247
248(deftest merge.4
249    (let ((A+B+C+standard (merge-readtables-into (copy-named-readtable 'A+B+C)
250                                                 :standard)))
251      (readtable= 'standard+A+B+C A+B+C+standard))
252  t)
253
254
255(deftest rename.1
256    (unwind-protect
257         (progn (make-readtable 'A* :merge '(A))
258                (rename-readtable 'A* 'A**)
259                (values (and (find-readtable 'A*) t)
260                        (and (find-readtable 'A**) t)))
261      (unregister-readtable 'A*)
262      (unregister-readtable 'A**))
263  nil
264  t)
265
266
267(deftest reader-macro-conflict.1
268    (signals-condition-p 'reader-macro-conflict
269      (merge-readtables-into (make-readtable) 'A 'A-as-X))
270  t)
271
272(deftest reader-macro-conflict.2
273    (signals-condition-p 'reader-macro-conflict
274      (merge-readtables-into (make-readtable) :standard :standard))
275  nil)
276
277(deftest reader-macro-conflict.3
278    (signals-condition-p 'reader-macro-conflict
279      (merge-readtables-into (make-readtable) 'A+B+C 'A))
280  nil)
281
282(deftest reader-macro-conflict.4
283    (signals-condition-p 'reader-macro-conflict
284      (merge-readtables-into (make-readtable) :standard 'sharp-paren))
285  t)
286
287(deftest reader-macro-conflict.5
288    (signals-condition-p 'reader-macro-conflict
289      (merge-readtables-into (make-readtable) 'A 'A-dispatch))
290  t)
291
292(deftest reader-macro-conflict.6
293    (signals-condition-p 'reader-macro-conflict
294      (merge-readtables-into (make-readtable) 'A-dispatch 'A))
295  t)
296
297(deftest reader-macro-conflict.7
298    (signals-condition-p 'reader-macro-conflict
299      (merge-readtables-into (make-readtable) 'A-dispatch 'A-dispatch-as-X))
300  t)
301
302(deftest reader-macro-conflict.8
303    (signals-condition-p 'reader-macro-conflict
304      (merge-readtables-into (make-readtable) 'A 'A))
305  nil)
306
307(deftest reader-macro-conflict.9
308    (signals-condition-p 'reader-macro-conflict
309      (merge-readtables-into (make-readtable) 'A-dispatch 'A-dispatch))
310  nil)
311
312
313(deftest readtable-does-not-exist.1
314    (signals-condition-p 'readtable-does-not-exist
315      (ensure-readtable 'does-not-exist))
316  t)
317
318
319(deftest readtable-does-already-exist.1
320    (signals-condition-p 'readtable-does-already-exist
321      (make-readtable 'A))
322  t)
323
324(deftest readtable-does-already-exist.2
325    (signals-condition-p 'readtable-does-already-exist
326      (make-readtable 'A))
327  t)
328
329(deftest readtable-does-already-exist.3
330    (let ((rt (make-readtable 'does-not-exist :merge '(:standard A B))))
331      (declare (ignore rt))
332      (unwind-protect
333           (read-with-readtable (continue-condition 'readtable-does-already-exist
334                                  (make-readtable 'does-not-exist
335                                                  :merge '(:standard A C)))
336                       
337                                "(A B C)")
338        (unregister-readtable 'does-not-exist)))
339    (:a B :c))
340
341
342(deftest defreadtable.1
343    (unwind-protect
344         (signals-condition-p 'reader-macro-conflict
345           (eval `(defreadtable does-not-exist (:merge A A-as-X))))
346      (unregister-readtable 'does-not-exist))
347  t)
348
349(deftest defreadtable.2
350    (unwind-protect
351         (signals-condition-p 't
352           (eval `(defreadtable does-not-exist (:fuse A A-as-X))))
353      (unregister-readtable 'does-not-exist))
354  nil)
355
Note: See TracBrowser for help on using the repository browser.