1 ;;;; This file is for testing external-format functionality for
2 ;;;; little-endian UCS-2, using test machinery which does not have
3 ;;;; side effects. Note that the tests here reach into unexported
4 ;;;; functionality, and should not be used as a guide for users.
6 ;;;; This software is part of the SBCL system. See the README file for
9 ;;;; While most of SBCL is derived from the CMU CL system, the test
10 ;;;; files (like this one) were written from scratch after the fork
13 ;;;; This software is in the public domain and is provided with
14 ;;;; absolutely no warranty. See the COPYING and CREDITS files for
15 ;;;; more information.
17 #-sb-unicode
(invoke-restart 'run-tests
::skip-file
)
19 (defvar *test-path
* (scratch-file-name))
21 (macrolet ((input-test (inxf expected
&environment env
)
23 (with-test (:name
(,(macroexpand 'name env
) :file
,inxf
))
24 (with-open-file (s *test-path
* :external-format
',inxf
)
25 (handler-bind ((sb-int:character-decoding-error
26 (lambda (c) (use-value "" c
))))
27 (let* ((string (make-string 20))
28 (count (read-sequence string s
)))
29 (assert (equal (map 'list
'identity
(subseq string
0 count
)) ,expected
))))))
30 (with-test (:name
(,(macroexpand 'name env
) :octets
,inxf
))
31 (handler-bind ((sb-int:character-decoding-error
32 (lambda (c) (use-value "" c
))))
33 (let ((octets (coerce bytes
'(simple-array (unsigned-byte 8) 1))))
34 (assert (equal (sb-ext:octets-to-string octets
:external-format
',inxf
)
35 (coerce ,expected
'string
))))))))
36 (with-input-bytes ((id bytes
) &body body
)
37 `(let ((bytes ,bytes
))
38 (with-open-file (s *test-path
* :element-type
'(unsigned-byte 8)
39 :direction
:output
:if-exists
:supersede
)
42 (symbol-macrolet ((name ,id
))
43 (macrolet ((test (inxf expected
)
44 `(input-test ,inxf
,expected
)))
46 (with-input-bytes ((:input
:invalid-units
) (list #x00
#x35
48 (test :ucs-2be
'(#\
5))
49 (test (:ucs-2be
:replacement
#\?) '(#\
5 #\?))))
51 (macrolet ((output-test (chars outxf expected
&environment env
)
53 (with-test (:name
(,(macroexpand 'name env
) file-string-length
,outxf
))
54 (let ((string (coerce ,chars
'string
)))
55 (with-open-file (s *test-path
* :element-type
'character
56 :external-format
',outxf
57 :direction
:output
:if-exists
:supersede
)
58 (handler-bind ((sb-int:character-encoding-error
59 (lambda (c) (use-value "" c
))))
60 (let ((pos (file-position s
))
61 (len (file-string-length s string
)))
63 (loop for index from
0 below
(length string
)
64 for char
= (char string index
)
65 for thislen
= (file-string-length s char
)
66 for thisstringlen
= (file-string-length s
(subseq string index
))
67 if
(null thisstringlen
) do
(assert (some 'null
(subseq ,expected index
))) else do
(assert (notany 'null
(subseq ,expected index
)))
69 if
(and (null len
) thisstringlen
) do
(setf len
(+ pos thisstringlen
))
70 if thisstringlen do
(assert (= (+ pos thisstringlen
) len
))
71 do
(write-char char s
)
72 if thislen do
(assert (= (+ pos thislen
) (file-position s
)))
73 do
(setf pos
(file-position s
)))))
74 (assert (equal actual
,expected
))))))))))
75 (with-output-characters ((id chars
) &body body
)
76 `(let ((chars ,chars
))
77 (symbol-macrolet ((name ,id
))
78 (macrolet ((test (outxf expected
)
79 `(output-test chars
,outxf
,expected
)))
81 (with-output-characters ((:output
:lf
) (list #\
5 #\LATIN_SMALL_LETTER_E_WITH_ACUTE
#\Linefeed
#\
7))
82 (test :ucs-2le
'(2 2 2 2)))
83 (with-output-characters ((:output
:invalid
:lf
) (list #\
5 #\LATIN_SMALL_LETTER_E_WITH_ACUTE
(code-char #x12345
) #\Linefeed
#\
7))
84 ;; A sufficiently-smart streams implementation could statically determine the lengths
85 ;; of replacement characters given as part of the external format
86 (test :ucs-2le
'(2 2 nil
2 2))
87 (test (:ucs-2le
:replacement
#\?) '(2 2 nil
2 2))))