1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-18 00:42:26 +02:00
guile/test-suite/tests/reader.test
Ludovic Courtès 89fc8adea3 Add test case to make sure `read' returns mutable strings.
* test-suite/tests/reader.test ("reading")["returned strings are
  mutable"]: New test, as reported by szgyg <szgyg@ludens.elte.hu>.
2008-10-09 23:24:07 +02:00

191 lines
6.5 KiB
Scheme
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;;;; reader.test --- Exercise the reader. -*- Scheme -*-
;;;;
;;;; Copyright (C) 1999, 2001, 2002, 2003, 2007, 2008 Free Software Foundation, Inc.
;;;; Jim Blandy <jimb@red-bean.com>
;;;;
;;;; This library is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU Lesser General Public
;;;; License as published by the Free Software Foundation; either
;;;; version 2.1 of the License, or (at your option) any later version.
;;;;
;;;; This library 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
;;;; Lesser General Public License for more details.
;;;;
;;;; You should have received a copy of the GNU Lesser General Public
;;;; License along with this library; if not, write to the Free Software
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
(define-module (test-suite reader)
:use-module (test-suite lib))
(define exception:eof
(cons 'read-error "end of file$"))
(define exception:unexpected-rparen
(cons 'read-error "unexpected \")\"$"))
(define exception:unterminated-block-comment
(cons 'read-error "unterminated `#! ... !#' comment$"))
(define exception:unknown-character-name
(cons 'read-error "unknown character name .*$"))
(define exception:unknown-sharp-object
(cons 'read-error "Unknown # object: .*$"))
(define exception:eof-in-string
(cons 'read-error "end of file in string constant$"))
(define exception:illegal-escape
(cons 'read-error "illegal character in escape sequence: .*$"))
(define (read-string s)
(with-input-from-string s (lambda () (read))))
(define (with-read-options opts thunk)
(let ((saved-options (read-options)))
(dynamic-wind
(lambda ()
(read-options opts))
thunk
(lambda ()
(read-options saved-options)))))
(with-test-prefix "reading"
(pass-if "0"
(equal? (read-string "0") 0))
(pass-if "1++i"
(equal? (read-string "1++i") '1++i))
(pass-if "1+i+i"
(equal? (read-string "1+i+i") '1+i+i))
(pass-if "1+e10000i"
(equal? (read-string "1+e10000i") '1+e10000i))
;; At one time the arg list for "Unknown # object: ~S" didn't make it out
;; of read.c. Check that `format' can be applied to this error.
(pass-if "error message on bad #"
(catch #t
(lambda ()
(read-string "#ZZZ")
;; oops, this # is supposed to be unrecognised
#f)
(lambda (key subr message args rest)
(apply format #f message args)
;; message and args are ok
#t)))
(pass-if "block comment"
(equal? '(+ 1 2 3)
(read-string "(+ 1 #! this is a\ncomment !# 2 3)")))
(pass-if "block comment finishing s-exp"
(equal? '(+ 2)
(read-string "(+ 2 #! a comment\n!#\n) ")))
(pass-if "unprintable symbol"
;; The reader tolerates unprintable characters for symbols.
(equal? (string->symbol "\001\002\003")
(read-string "\001\002\003")))
(pass-if "CR recognized as a token delimiter"
;; In 1.8.3, character 0x0d was not recognized as a delimiter.
(equal? (read-string "one\x0dtwo") 'one))
(pass-if "returned strings are mutable"
;; Per R5RS Section 3.4, "Storage Model", `read' is supposed to return
;; mutable objects.
(let ((str (with-input-from-string "\"hello, world\"" read)))
(string-set! str 0 #\H)
(string=? str "Hello, world"))))
(pass-if-exception "radix passed to number->string can't be zero"
exception:out-of-range
(number->string 10 0))
(pass-if-exception "radix passed to number->string can't be one either"
exception:out-of-range
(number->string 10 1))
(with-test-prefix "mismatching parentheses"
(pass-if-exception "opening parenthesis"
exception:eof
(read-string "("))
(pass-if-exception "closing parenthesis following mismatched opening"
exception:unexpected-rparen
(read-string ")"))
(pass-if-exception "opening vector parenthesis"
exception:eof
(read-string "#("))
(pass-if-exception "closing parenthesis following mismatched vector opening"
exception:unexpected-rparen
(read-string ")")))
(with-test-prefix "exceptions"
;; Reader exceptions: although they are not documented, they may be relied
;; on by some programs, hence these tests.
(pass-if-exception "unterminated block comment"
exception:unterminated-block-comment
(read-string "(+ 1 #! comment\n..."))
(pass-if-exception "unknown character name"
exception:unknown-character-name
(read-string "#\\theunknowncharacter"))
(pass-if-exception "unknown sharp object"
exception:unknown-sharp-object
(read-string "#?"))
(pass-if-exception "eof in string"
exception:eof-in-string
(read-string "\"the string that never ends"))
(pass-if-exception "illegal escape in string"
exception:illegal-escape
(read-string "\"some string \\???\"")))
(with-test-prefix "read-options"
(pass-if "case-sensitive"
(not (eq? 'guile 'GuiLe)))
(pass-if "case-insensitive"
(eq? 'guile
(with-read-options '(case-insensitive)
(lambda ()
(read-string "GuiLe")))))
(pass-if "prefix keywords"
(eq? #:keyword
(with-read-options '(keywords prefix case-insensitive)
(lambda ()
(read-string ":KeyWord")))))
(pass-if "prefix non-keywords"
(symbol? (with-read-options '(keywords prefix)
(lambda ()
(read-string "srfi88-keyword:")))))
(pass-if "postfix keywords"
(eq? #:keyword
(with-read-options '(keywords postfix)
(lambda ()
(read-string "keyword:")))))
(pass-if "`:' is not a postfix keyword (per SRFI-88)"
(eq? ':
(with-read-options '(keywords postfix)
(lambda ()
(read-string ":")))))
(pass-if "no positions"
(let ((sexp (with-read-options '()
(lambda ()
(read-string "(+ 1 2 3)")))))
(and (not (source-property sexp 'line))
(not (source-property sexp 'column)))))
(pass-if "positions"
(let ((sexp (with-read-options '(positions)
(lambda ()
(read-string "(+ 1 2 3)")))))
(and (equal? (source-property sexp 'line) 0)
(equal? (source-property sexp 'column) 0))))
(pass-if "positions on quote"
(let ((sexp (with-read-options '(positions)
(lambda ()
(read-string "'abcde")))))
(and (equal? (source-property sexp 'line) 0)
(equal? (source-property sexp 'column) 0)))))