;; -*- coding: utf-8 -*- ;;; Copyright (C) Per Bothner (2017). ;;; Copyright (C) William D Clinger (2016). ;;; ;;; Permission is hereby granted, free of charge, to any person ;;; obtaining a copy of this software and associated documentation ;;; files (the "Software"), to deal in the Software without ;;; restriction, including without limitation the rights to use, ;;; copy, modify, merge, publish, distribute, sublicense, and/or ;;; sell copies of the Software, and to permit persons to whom the ;;; Software is furnished to do so, subject to the following ;;; conditions: ;;; ;;; The above copyright notice and this permission notice shall be ;;; included in all copies or substantial portions of the Software. ;;; ;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ;;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ;;; OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ;;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ;;; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ;;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ;;; OTHER DEALINGS IN THE SOFTWARE. #| (import (scheme base) (scheme write) (scheme char) (srfi 140)) |# (test-begin "strings") #| ;;; Help functions for testing. (define (as-string . args) (string-concatenate (map (lambda (x) (cond ((string? x) x) ((char? x) (string x)) (else (error "as-string: illegal argument" x)))) args))) |# ;;; Unicode is a strong motivation for immutable strings, so we ought ;;; to use at least some non-ASCII strings for testing. ;;; Some systems would blow up if this file were to contain non-ASCII ;;; characters, however, so we have to be careful here. ;;; ;;; FIXME: need more tests with really high code points (cond-expand ((or sagittarius chibi kawa full-unicode-strings) (define ABC (list->string (map integer->char '(#x3b1 #x3b2 #x3b3)))) (define ABCDEF (list->string (map integer->char '(#x0c0 #x062 #x0c7 #x064 #x0c9 #x066)))) (define DEFABC (list->string (map integer->char '(#x064 #x0c9 #x066 #x0c0 #x062 #x0c7)))) (define eszett (integer->char #xDF)) (define fuss (string #\F #\u eszett)) (define chaos0 (list->string (map integer->char '(#x39E #x391 #x39F #x3A3)))) (define chaos1 (list->string (map integer->char '(#x3BE #x3B1 #x3BF #x3C2)))) (define chaos2 (list->string (map integer->char '(#x3BE #x3B1 #x3BF #x3C3)))) (define beyondBMP (list->string (map integer->char '(#x61 #xc0 #x3bf #x1d441 #x1d113 #x1d110 #x7a))))) (else (define ABC "abc") (define ABCDEF "ABCdef") (define DEFABC "defabc"))) ;;; Predicates (test-assert (string? (string))) (test-assert (not (string? #\a))) (test-assert (string-null? (string))) (test-assert (not (string-null? ABC))) (define (check-istring str) (list (istring? str) (string-length str))) (test-equal '(#t 0) (check-istring "")) (test-equal '(#t 4) (check-istring "abcd")) (test-equal '(#t 4) (check-istring (string #\A #\b #\c #\d))) (test-equal '(#t 3) (check-istring (substring (make-string 4 #\X) 1 4))) (test-equal '(#f 4) (check-istring (make-string 4 #\X))) (test-equal '(#f 4) (check-istring (string-copy (make-string 4 #\X)))) (test-equal '(#f 3) (check-istring (string-copy (make-string 4 #\X) 1 4))) (test-equal '(#t 3) (check-istring (vector->string #(#\x #\y #\z)))) (test-equal '(#t 3) (check-istring (vector->string #(#\x #\y #\z)))) (test-equal '(#t 3) (check-istring (list->string '(#\x #\y #\z)))) (test-equal '(#t 3) (check-istring (reverse-list->string '(#\x #\y #\z)))) (test-equal '(#t 3) (check-istring (utf8->string (string->utf8 "abc")))) (test-equal '(#t 3) (check-istring (utf16->string (string->utf16 "abc")))) (test-equal '(#t 3) (check-istring (utf16be->string (string->utf16be "abc")))) (test-equal '(#t 3) (check-istring (utf16le->string (string->utf16le "abc")))) (test-equal '(#t 2) (check-istring (string-take "abcd" 2))) (test-equal '(#t 2) (check-istring (string-drop "abcd" 2))) (test-equal '(#t 2) (check-istring (string-take-right "abcd" 2))) (test-equal '(#t 2) (check-istring (string-drop-right "abcd" 2))) (test-equal '(#t 5) (check-istring (string-pad "abcd" 5))) (test-equal '(#t 3) (check-istring (string-pad-right "abcd" 3))) (test-equal '(#t 2) (check-istring (string-trim " A "))) (test-equal '(#t 3) (check-istring (string-trim-right " A "))) (test-equal '(#t 1) (check-istring (string-trim-both " A "))) (test-equal '(#t 3) (check-istring (string-replace "AB" "X" 1 1))) (test-equal '(#t 3) (check-istring (string-upcase (make-string 3 #\X)))) (test-equal '(#t 3) (check-istring (string-downcase (make-string 3 #\x)))) (test-equal '(#t 3) (check-istring (string-foldcase (make-string 3 #\x)))) (test-equal '(#t 3) (check-istring (string-titlecase (make-string 3 #\X)))) (test-equal '(#t 6) (check-istring (string-append "abcd" "XY"))) (test-equal '(#t 6) (check-istring (string-concatenate (list "abcd" "XY")))) (test-equal '(#t 6) (check-istring (string-concatenate-reverse (list "abcd" "XY")))) (test-equal '(#t 7) (check-istring (string-join (list "abc" "xyz")))) (test-equal '(#t 3) (check-istring (string-map char-upcase "abc"))) (test-equal '(#t 6) (check-istring (string-repeat "ab" 3))) (test-equal '(#t 14) (check-istring (xsubstring "abcdef" -4 10))) (test-equal '(#t 3) (check-istring (cadr (string-split "ab cef" " ")))) (test-expect-fail 1) (test-equal '(#t 5) (check-istring (symbol->string 'Hello))) (test-equal #t (string-every (lambda (c) (if (char? c) c #f)) (string))) (test-equal #\c (string-every (lambda (c) (if (char? c) c #f)) "abc")) (test-equal #f (string-every (lambda (c) (if (char>? c #\b) c #f)) "abc")) (test-equal #\c (string-every (lambda (c) (if (char>? c #\b) c #f)) "abc" 2)) (test-equal #t (string-every (lambda (c) (if (char>? c #\b) c #f)) "abc" 1 1)) (test-equal #f (string-any (lambda (c) (if (char? c) c #f)) (string))) (test-equal #\a (string-any (lambda (c) (if (char? c) c #f)) "abc")) (test-equal #\c (string-any (lambda (c) (if (char>? c #\b) c #f)) "abc")) (test-equal #\c (string-any (lambda (c) (if (char>? c #\b) c #f)) "abc" 2)) (test-equal #f (string-any (lambda (c) (if (char>? c #\b) c #f)) "abc" 0 2)) (test-equal #t (string-every (lambda (c) (if (char? c) c #f)) "")) (test-equal #\c (string-every (lambda (c) (if (char? c) c #f)) "abc")) (test-equal #f (string-every (lambda (c) (if (char>? c #\b) c #f)) "abc")) (test-equal #\c (string-every (lambda (c) (if (char>? c #\b) c #f)) "abc" 2)) (test-equal #t (string-every (lambda (c) (if (char>? c #\b) c #f)) "abc" 1 1)) (test-equal #f (string-any (lambda (c) (if (char? c) c #f)) "")) (test-equal #\a (string-any (lambda (c) (if (char? c) c #f)) "abc")) (test-equal #\c (string-any (lambda (c) (if (char>? c #\b) c #f)) "abc")) (test-equal #\c (string-any (lambda (c) (if (char>? c #\b) c #f)) "abc" 2)) (test-equal #f (string-any (lambda (c) (if (char>? c #\b) c #f)) "abc" 0 2)) ;;; Constructors (test-equal "" (string-tabulate (lambda (i) (integer->char (+ i (char->integer #\a)))) 0)) (let ((r (string-tabulate (lambda (i) (integer->char (+ i (char->integer #\a)))) 3))) (test-equal '(#t 3) (check-istring r)) (test-equal "abc" r)) (let* ((p (open-input-string "abc")) (r (string-unfold eof-object? values (lambda (x) (read-char p)) (read-char p)))) (test-equal '(#t 3) (check-istring r)) (test-equal "abc" r)) (test-equal "" (string-unfold null? car cdr '())) (test-equal "abc" (string-unfold null? car cdr (string->list "abc"))) (test-equal "def" (string-unfold null? car cdr '() "def")) (test-equal "defabcG" (string-unfold null? car cdr (string->list "abc") "def" (lambda (x) (if (null? x) (string #\G) "")))) (test-equal "" (string-unfold-right null? car cdr '())) (test-equal "cba" (string-unfold-right null? car cdr (string->list "abc"))) (test-equal "def" (string-unfold-right null? car cdr '() "def")) (test-equal '(#t 3) (check-istring (string-unfold-right null? car cdr '() "def"))) (test-equal "Gcbadef" (string-unfold-right null? car cdr (string->list "abc") "def" (lambda (x) (if (null? x) (string #\G) "")))) (test-equal "def" (string-unfold null? car cdr '() "def")) (test-equal "defabcG" (string-unfold null? car cdr (string->list "abc") "def" (lambda (x) (if (null? x) "G" "")))) (test-equal "dabcG" (string-unfold null? car cdr (string->list "abc") #\d (lambda (x) (if (null? x) "G" "")))) (test-equal (string-append "%=" (make-string 200 #\*) "A B C D E F G H I J K L M " "N O P Q R S T U V W X Y Z " (make-string (* 200 (- (char->integer #\a) (char->integer #\Z) 1)) #\*) "abcdefghijklmnopqrstuvwxyz" " ") (string-unfold (lambda (n) (char>? (integer->char n) #\z)) (lambda (n) (let ((c (integer->char n))) (cond ((char<=? #\a c #\z) c) ((char<=? #\A c #\Z) (string c #\space)) (else (make-string 200 #\*))))) (lambda (n) (+ n 1)) (char->integer #\@) "%=" (lambda (n) #\space))) (test-equal "def" (string-unfold-right null? car cdr '() "def")) (test-equal "Gcbadef" (string-unfold-right null? car cdr (string->list "abc") "def" (lambda (x) (if (null? x) "G" "")))) (test-equal "Gcbad" (string-unfold-right null? car cdr (string->list "abc") #\d (lambda (x) (if (null? x) "G" "")))) (test-equal (string-append " " (list->string (reverse (string->list "abcdefghijklmnopqrstuvwxyz"))) (make-string (* 200 (- (char->integer #\a) (char->integer #\Z) 1)) #\*) "Z Y X W V U T S R Q P O N " "M L K J I H G F E D C B A " (make-string 200 #\*) "%=") (string-unfold-right (lambda (n) (char>? (integer->char n) #\z)) (lambda (n) (let ((c (integer->char n))) (cond ((char<=? #\a c #\z) c) ((char<=? #\A c #\Z) (string c #\space)) (else (make-string 200 #\*))))) (lambda (n) (+ n 1)) (char->integer #\@) "%=" (lambda (n) #\space))) (test-equal " The English alphabet: abcdefghijklmnopqrstuvwxyz " (string-unfold-right (lambda (n) (< n (char->integer #\A))) (lambda (n) (char-downcase (integer->char n))) (lambda (n) (- n 1)) (char->integer #\Z) #\space (lambda (n) " The English alphabet: "))) ;;; Conversion (let ((txt (string #\s #\t #\r))) (test-assert (and (string? txt) (string=? txt "str")))) (test-equal "" (string)) (test-equal "" (substring (string) 0 0)) (test-equal "abc" (string #\a #\b #\c)) (test-equal "" (substring (string #\a #\b #\c) 3 3)) (test-equal "bc" (substring (string #\a #\b #\c) 1 3)) ;(test-equal "" (substring "" 0)) (test-equal "" (substring "" 0 0)) (test-equal "" (substring "abc" 3 3)) (test-equal "bc" (substring "abc" 1 3)) (test-equal '#() (string->vector (string))) ;(test-equal '#() (string->vector (string) 0)) (test-equal '#() (string->vector (string) 0 0)) (test-equal '#(#\a #\b #\c) (string->vector (string #\a #\b #\c))) (test-equal '#() (string->vector (string #\a #\b #\c) 3)) (test-equal '#(#\b #\c) (string->vector (string #\a #\b #\c) 1 3)) (test-equal '#() (string->vector "")) (test-equal '#() (string->vector "" 0)) (test-equal '#() (string->vector "" 0 0)) (test-equal '#(#\a #\b #\c) (string->vector "abc")) (test-equal '#() (string->vector "abc" 3)) (test-equal '#(#\b #\c) (string->vector "abc" 1 3)) (test-equal '() (string->list (string))) (test-equal '() (string->list (string) 0)) (test-equal '() (string->list (string) 0 0)) (test-equal '(#\a #\b #\c) (string->list (string #\a #\b #\c))) (test-equal '() (string->list (string #\a #\b #\c) 3)) (test-equal '(#\b #\c) (string->list (string #\a #\b #\c) 1 3)) (test-equal '() (string->list "")) (test-equal '() (string->list "" 0)) (test-equal '() (string->list "" 0 0)) (test-equal '(#\a #\b #\c) (string->list "abc")) (test-equal '() (string->list "abc" 3)) (test-equal '(#\b #\c) (string->list "abc" 1 3)) (test-equal "" "") (test-equal "" (substring "" 0 0)) (test-equal "bc" (substring "abc" 1 3)) (test-equal "" (substring "abc" 3 3)) (test-equal "b" (substring "abc" 1 2)) (test-equal "bc" (substring "abc" 1 3)) (test-equal "" (vector->string '#())) (test-equal "" (vector->string '#() 0)) (test-equal "" (vector->string '#() 0 0)) (test-equal "abc" (vector->string '#(#\a #\b #\c))) (test-equal "bc" (vector->string '#(#\a #\b #\c) 1)) (test-equal "" (vector->string '#(#\a #\b #\c) 3)) (test-equal "b" (vector->string '#(#\a #\b #\c) 1 2)) (test-equal "bc" (vector->string '#(#\a #\b #\c) 1 3)) (test-equal "" (list->string '())) #| FIXME TODO (test-equal "" (list->string '() 0)) (test-equal "" (list->string '() 0 0)) (test-equal "abc" (list->string '(#\a #\b #\c))) (test-equal "bc" (list->string '(#\a #\b #\c) 1)) (test-equal "" (list->string '(#\a #\b #\c) 3)) (test-equal "b" (list->string '(#\a #\b #\c) 1 2)) (test-equal "bc" (list->string '(#\a #\b #\c) 1 3)) |# (test-equal "" (reverse-list->string '())) (test-equal "cba" (reverse-list->string '(#\a #\b #\c))) (test-equal '#u8(97 98 99) (string->utf8 "abc")) (test-equal '#u8(97 98 99 121 121 121 122 122 122) (string->utf8 "xxxabcyyyzzz" 3)) (test-equal '#u8(97 98 99) (string->utf8 "xxxabcyyyzzz" 3 6)) (test-equal (cond-expand (big-endian '#u8(254 255 0 97 0 98 0 99)) (else '#u8(255 254 97 0 98 0 99 0))) (string->utf16 "abc")) (test-equal (cond-expand (big-endian '#u8(254 255 0 97 0 98 0 99 0 121 0 121 0 121 0 122 0 122 0 122)) (else '#u8(255 254 97 0 98 0 99 0 121 0 121 0 121 0 122 0 122 0 122 0))) (string->utf16 "xxxabcyyyzzz" 3)) (test-equal (cond-expand (big-endian '#u8(254 255 0 97 0 98 0 99)) (else '#u8(255 254 97 0 98 0 99 0))) (string->utf16 "xxxabcyyyzzz" 3 6)) (test-equal '#u8(0 97 0 98 0 99) (string->utf16be "abc")) (test-equal '#u8(0 97 0 98 0 99 0 121 0 121 0 121 0 122 0 122 0 122) (string->utf16be "xxxabcyyyzzz" 3)) (test-equal '#u8(0 97 0 98 0 99) (string->utf16be "xxxabcyyyzzz" 3 6)) (test-equal '#u8(97 0 98 0 99 0) (string->utf16le "abc")) (test-equal '#u8(97 0 98 0 99 0 121 0 121 0 121 0 122 0 122 0 122 0) (string->utf16le "xxxabcyyyzzz" 3)) (test-equal '#u8(97 0 98 0 99 0) (string->utf16le "xxxabcyyyzzz" 3 6)) (test-equal "abc" (utf8->string '#u8(97 98 99))) (test-equal "abcyyyzzz" (utf8->string '#u8(0 1 2 97 98 99 121 121 121 122 122 122) 3)) (test-equal "abc" (utf8->string '#u8(41 42 43 97 98 99 100 101 102) 3 6)) (test-equal "abc" (utf16->string '#u8(254 255 0 97 0 98 0 99))) (test-equal "abc" (utf16->string '#u8(255 254 97 0 98 0 99 0))) (test-equal "abc" (utf16->string (string->utf16 "abc") 2)) (test-equal "bcdef" (utf16->string (string->utf16 "abcdef") 4)) (test-equal "bcd" (utf16->string (string->utf16 "abcdef") 4 10)) (test-equal "abc" (utf16be->string '#u8(0 97 0 98 0 99))) (test-equal "bc" (utf16be->string (string->utf16be "abc") 2)) (test-equal "bcd" (utf16be->string (string->utf16be "abcdef") 2 8)) (test-equal "abc" (utf16le->string '#u8(97 0 98 0 99 0))) (test-equal "bc" (utf16le->string (string->utf16le "abc") 2)) (test-equal "bcd" (utf16le->string (string->utf16le "abcdef") 2 8)) (cond-expand ((or sagittarius chibi kawa full-unicode-strings) (test-equal '#u8(97 195 128 206 191 240 157 145 129 240 157 132 147 240 157 132 144 122) (string->utf8 beyondBMP)) (let ((bv (string->utf16 beyondBMP))) (test-assert (or (equal? bv '#u8(254 255 0 97 0 192 3 191 216 53 220 65 216 52 221 19 216 52 221 16 0 122)) (equal? bv '#u8(255 254 97 0 192 0 191 3 53 216 65 220 52 216 19 221 52 216 16 221 122 0))))) (test-equal '#u8(0 97 0 192 3 191 216 53 220 65 216 52 221 19 216 52 221 16 0 122) (string->utf16be beyondBMP)) (test-equal '#u8(97 0 192 0 191 3 53 216 65 220 52 216 19 221 52 216 16 221 122 0) (string->utf16le beyondBMP)) (test-equal beyondBMP (utf8->string '#u8(97 195 128 206 191 240 157 145 129 240 157 132 147 240 157 132 144 122))) (test-equal beyondBMP (utf16->string (string->utf16 beyondBMP))) (test-equal beyondBMP (utf16->string (string->utf16 beyondBMP) 2)) (test-equal beyondBMP (utf16be->string (string->utf16be beyondBMP))) (test-equal beyondBMP (utf16le->string (string->utf16le beyondBMP))) (test-equal (string-append (string (integer->char #xfeff)) "abc") (utf16be->string '#u8(254 255 0 97 0 98 0 99))) (test-equal (string-append (string (integer->char #xfeff)) "abc") (utf16le->string '#u8(255 254 97 0 98 0 99 0))) ) (else)) ;;; Selection (test-equal 0 (string-length (string))) (test-equal 6 (string-length ABCDEF)) (test-equal 1234 (string-length (make-string 1234 (string-ref ABC 0)))) (test-equal #\a (string-ref (string #\a #\b #\c) 0)) (test-equal #\c (string-ref (string #\a #\b #\c) 2)) (test-equal 0 (string-length (string))) (test-equal 6 (string-length ABCDEF)) (test-equal 1234 (string-length (make-string 1234 (string-ref ABC 0)))) (test-equal #\a (string-ref (string #\a #\b #\c) 0)) (test-equal #\c (string-ref (string #\a #\b #\c) 2)) (test-equal "" (substring (string) 0 0)) (test-equal "" (substring "abcdef" 0 0)) (test-equal "" (substring "abcdef" 4 4)) (test-equal "" (substring "abcdef" 6 6)) (test-equal "abcd" (substring "abcdef" 0 4)) (test-equal "cde" (substring "abcdef" 2 5)) (test-equal "cdef" (substring "abcdef" 2 6)) (test-equal "abcdef" (substring "abcdef" 0 6)) (test-equal "" (substring (string) 0 0)) (test-equal "" (substring "abcdef" 0 0)) (test-equal "" (substring "abcdef" 4 4)) (test-equal "" (substring "abcdef" 6 6)) (test-equal "abcd" (substring "abcdef" 0 4)) (test-equal "cde" (substring "abcdef" 2 5)) (test-equal "cdef" (substring "abcdef" 2 6)) (test-equal "abcdef" (substring "abcdef" 0 6)) (test-equal "" (substring "" 0 0)) (test-equal "" (substring "abcdef" 0 0)) (test-equal "" (substring "abcdef" 4 4)) (test-equal "" (substring "abcdef" 6 6)) (test-equal "abcd" (substring "abcdef" 0 4)) (test-equal "cde" (substring "abcdef" 2 5)) (test-equal "cdef" (substring "abcdef" 2 6)) (test-equal "abcdef" (substring "abcdef" 0 6)) (test-equal "" (string-copy (string))) (let* ((txt "abcdef") (copy (string-copy txt))) (test-equal "abcdef" copy) (test-assert (not (eqv? txt copy)))) (test-equal "" (string-copy "")) (test-equal "abcdef" (string-copy "abcdef")) (test-equal "" (string-copy (string) 0)) (test-equal "abcdef" (string-copy "abcdef" 0)) (test-equal "ef" (string-copy "abcdef" 4)) (test-equal "" (string-copy "abcdef" 6)) (test-equal "" (string-copy "" 0)) (test-equal "abcdef" (string-copy "abcdef" 0)) (test-equal "ef" (string-copy "abcdef" 4)) (test-equal "" (string-copy "abcdef" 6)) (test-equal "" (string-copy (string) 0 0)) (test-equal "" (string-copy "abcdef" 0 0)) (test-equal "" (string-copy "abcdef" 4 4)) (test-equal "" (string-copy "abcdef" 6 6)) (test-equal "abcd" (string-copy "abcdef" 0 4)) (test-equal "cde" (string-copy "abcdef" 2 5)) (test-equal "cdef" (string-copy "abcdef" 2 6)) (test-equal "abcdef" (string-copy "abcdef" 0 6)) (test-equal "" (string-copy "" 0 0)) (test-equal "" (string-copy "abcdef" 0 0)) (test-equal "" (string-copy "abcdef" 4 4)) (test-equal "" (string-copy "abcdef" 6 6)) (test-equal "abcd" (string-copy "abcdef" 0 4)) (test-equal "cde" (string-copy "abcdef" 2 5)) (test-equal "cdef" (string-copy "abcdef" 2 6)) (test-equal "abcdef" (string-copy "abcdef" 0 6)) (test-equal "" (string-take (string) 0)) (test-equal "" (string-take "abcdef" 0)) (test-equal "ab" (string-take "abcdef" 2)) (test-equal "" (string-drop "" 0)) (test-equal "abcdef" (string-drop "abcdef" 0)) (test-equal "cdef" (string-drop "abcdef" 2)) (test-equal "" (string-take-right (string) 0)) (test-equal "" (string-take-right "abcdef" 0)) (test-equal "ef" (string-take-right "abcdef" 2)) (test-equal "" (string-drop-right (string) 0)) (test-equal "abcdef" (string-drop-right "abcdef" 0)) (test-equal "abcd" (string-drop-right "abcdef" 2)) (test-equal "" (string-take "" 0)) (test-equal "" (string-take "abcdef" 0)) (test-equal "ab" (string-take "abcdef" 2)) (test-equal "" (string-drop "" 0)) (test-equal "abcdef" (string-drop "abcdef" 0)) (test-equal "cdef" (string-drop "abcdef" 2)) (test-equal "" (string-take-right "" 0)) (test-equal "" (string-take-right "abcdef" 0)) (test-equal "ef" (string-take-right "abcdef" 2)) (test-equal "" (string-drop-right "" 0)) (test-equal "abcdef" (string-drop-right "abcdef" 0)) (test-equal "abcd" (string-drop-right "abcdef" 2)) (test-equal "" (string-pad "" 0)) (test-equal " " (string-pad "" 5)) (test-equal " 325" (string-pad "325" 5)) (test-equal "71325" (string-pad "71325" 5)) (test-equal "71325" (string-pad "8871325" 5)) (test-equal "" (string-pad "" 0 #\*)) (test-equal "*****" (string-pad "" 5 #\*)) (test-equal "**325" (string-pad "325" 5 #\*)) (test-equal "71325" (string-pad "71325" 5 #\*)) (test-equal "71325" (string-pad "8871325" 5 #\*)) (test-equal "" (string-pad "" 0 #\* 0)) (test-equal "*****" (string-pad "" 5 #\* 0)) (test-equal "**325" (string-pad "325" 5 #\* 0)) (test-equal "71325" (string-pad "71325" 5 #\* 0)) (test-equal "71325" (string-pad "8871325" 5 #\* 0)) (test-equal "***25" (string-pad "325" 5 #\* 1)) (test-equal "*1325" (string-pad "71325" 5 #\* 1)) (test-equal "71325" (string-pad "8871325" 5 #\* 1)) (test-equal "" (string-pad "" 0 #\* 0 0)) (test-equal "*****" (string-pad "" 5 #\* 0 0)) (test-equal "**325" (string-pad "325" 5 #\* 0 3)) (test-equal "**713" (string-pad "71325" 5 #\* 0 3)) (test-equal "**887" (string-pad "8871325" 5 #\* 0 3)) (test-equal "***25" (string-pad "325" 5 #\* 1 3)) (test-equal "**132" (string-pad "71325" 5 #\* 1 4)) (test-equal "*8713" (string-pad "8871325" 5 #\* 1 5)) (test-equal "" (string-pad-right "" 0)) (test-equal " " (string-pad-right "" 5)) (test-equal "325 " (string-pad-right "325" 5)) (test-equal "71325" (string-pad-right "71325" 5)) (test-equal "88713" (string-pad-right "8871325" 5)) (test-equal "" (string-pad-right "" 0 #\*)) (test-equal "*****" (string-pad-right "" 5 #\*)) (test-equal "325**" (string-pad-right "325" 5 #\*)) (test-equal "71325" (string-pad-right "71325" 5 #\*)) (test-equal "88713" (string-pad-right "8871325" 5 #\*)) (test-equal "" (string-pad-right "" 0 #\* 0)) (test-equal "*****" (string-pad-right "" 5 #\* 0)) (test-equal "325**" (string-pad-right "325" 5 #\* 0)) (test-equal "71325" (string-pad-right "71325" 5 #\* 0)) (test-equal "88713" (string-pad-right "8871325" 5 #\* 0)) (test-equal "25***" (string-pad-right "325" 5 #\* 1)) (test-equal "1325*" (string-pad-right "71325" 5 #\* 1)) (test-equal "87132" (string-pad-right "8871325" 5 #\* 1)) (test-equal "" (string-pad-right "" 0 #\* 0 0)) (test-equal "*****" (string-pad-right "" 5 #\* 0 0)) (test-equal "325**" (string-pad-right "325" 5 #\* 0 3)) (test-equal "713**" (string-pad-right "71325" 5 #\* 0 3)) (test-equal "887**" (string-pad-right "8871325" 5 #\* 0 3)) (test-equal "25***" (string-pad-right "325" 5 #\* 1 3)) (test-equal "132**" (string-pad-right "71325" 5 #\* 1 4)) (test-equal "8713*" (string-pad-right "8871325" 5 #\* 1 5)) (test-equal "" (string-pad "" 0)) (test-equal " " (string-pad "" 5)) (test-equal " 325" (string-pad "325" 5)) (test-equal "71325" (string-pad "71325" 5)) (test-equal "71325" (string-pad "8871325" 5)) (test-equal "" (string-pad "" 0 #\*)) (test-equal "*****" (string-pad "" 5 #\*)) (test-equal "**325" (string-pad "325" 5 #\*)) (test-equal "71325" (string-pad "71325" 5 #\*)) (test-equal "71325" (string-pad "8871325" 5 #\*)) (test-equal "" (string-pad "" 0 #\* 0)) (test-equal "*****" (string-pad "" 5 #\* 0)) (test-equal "**325" (string-pad "325" 5 #\* 0)) (test-equal "71325" (string-pad "71325" 5 #\* 0)) (test-equal "71325" (string-pad "8871325" 5 #\* 0)) (test-equal "***25" (string-pad "325" 5 #\* 1)) (test-equal "*1325" (string-pad "71325" 5 #\* 1)) (test-equal "71325" (string-pad "8871325" 5 #\* 1)) (test-equal "" (string-pad "" 0 #\* 0 0)) (test-equal "*****" (string-pad "" 5 #\* 0 0)) (test-equal "**325" (string-pad "325" 5 #\* 0 3)) (test-equal "**713" (string-pad "71325" 5 #\* 0 3)) (test-equal "**887" (string-pad "8871325" 5 #\* 0 3)) (test-equal "***25" (string-pad "325" 5 #\* 1 3)) (test-equal "**132" (string-pad "71325" 5 #\* 1 4)) (test-equal "*8713" (string-pad "8871325" 5 #\* 1 5)) (test-equal "" (string-pad-right "" 0)) (test-equal " " (string-pad-right "" 5)) (test-equal "325 " (string-pad-right "325" 5)) (test-equal "71325" (string-pad-right "71325" 5)) (test-equal "88713" (string-pad-right "8871325" 5)) (test-equal "" (string-pad-right "" 0 #\*)) (test-equal "*****" (string-pad-right "" 5 #\*)) (test-equal "325**" (string-pad-right "325" 5 #\*)) (test-equal "71325" (string-pad-right "71325" 5 #\*)) (test-equal "88713" (string-pad-right "8871325" 5 #\*)) (test-equal "" (string-pad-right "" 0 #\* 0)) (test-equal "*****" (string-pad-right "" 5 #\* 0)) (test-equal "325**" (string-pad-right "325" 5 #\* 0)) (test-equal "71325" (string-pad-right "71325" 5 #\* 0)) (test-equal "88713" (string-pad-right "8871325" 5 #\* 0)) (test-equal "25***" (string-pad-right "325" 5 #\* 1)) (test-equal "1325*" (string-pad-right "71325" 5 #\* 1)) (test-equal "87132" (string-pad-right "8871325" 5 #\* 1)) (test-equal "" (string-pad-right "" 0 #\* 0 0)) (test-equal "*****" (string-pad-right "" 5 #\* 0 0)) (test-equal "325**" (string-pad-right "325" 5 #\* 0 3)) (test-equal "713**" (string-pad-right "71325" 5 #\* 0 3)) (test-equal "887**" (string-pad-right "8871325" 5 #\* 0 3)) (test-equal "25***" (string-pad-right "325" 5 #\* 1 3)) (test-equal "132**" (string-pad-right "71325" 5 #\* 1 4)) (test-equal "8713*" (string-pad-right "8871325" 5 #\* 1 5)) (test-equal "" (string-trim "")) (test-equal "a b c " (string-trim " a b c ")) (test-equal "" (string-trim "" char-whitespace?)) (test-equal "a b c " (string-trim " a b c " char-whitespace?)) (test-equal "" (string-trim " a b c " char?)) (test-equal "" (string-trim "" char-whitespace? 0)) (test-equal "a b c " (string-trim " a b c " char-whitespace? 0)) (test-equal "" (string-trim " a b c " char? 0)) (test-equal "b c " (string-trim " a b c " char-whitespace? 3)) (test-equal "" (string-trim " a b c " char? 3)) (test-equal "" (string-trim " a b c " char? 0 11)) (test-equal "b c " (string-trim " a b c " char-whitespace? 3 11)) (test-equal "" (string-trim " a b c " char? 3 11)) (test-equal "" (string-trim " a b c " char? 0 8)) (test-equal "b " (string-trim " a b c " char-whitespace? 3 8)) (test-equal "" (string-trim " a b c " char? 3 8)) (test-equal "" (string-trim-right "")) (test-equal " a b c" (string-trim-right " a b c ")) (test-equal "" (string-trim-right "" char-whitespace?)) (test-equal " a b c" (string-trim-right " a b c " char-whitespace?)) (test-equal "" (string-trim-right " a b c " char?)) (test-equal "" (string-trim-right "" char-whitespace? 0)) (test-equal " a b c" (string-trim-right " a b c " char-whitespace? 0)) (test-equal "" (string-trim-right " a b c " char? 0)) (test-equal " b c" (string-trim-right " a b c " char-whitespace? 3)) (test-equal "" (string-trim-right " a b c " char? 3)) (test-equal "" (string-trim-right " a b c " char? 0 11)) (test-equal " b c" (string-trim-right " a b c " char-whitespace? 3 11)) (test-equal "" (string-trim-right " a b c " char? 3 11)) (test-equal "" (string-trim-right " a b c " char? 0 8)) (test-equal " b" (string-trim-right " a b c " char-whitespace? 3 8)) (test-equal "" (string-trim-right " a b c " char? 3 8)) (test-equal "" (string-trim-both "")) (test-equal "a b c" (string-trim-both " a b c ")) (test-equal "" (string-trim-both "" char-whitespace?)) (test-equal "a b c" (string-trim-both " a b c " char-whitespace?)) (test-equal "" (string-trim-both " a b c " char?)) (test-equal "" (string-trim-both "" char-whitespace? 0)) (test-equal "a b c" (string-trim-both " a b c " char-whitespace? 0)) (test-equal "" (string-trim-both " a b c " char? 0)) (test-equal "b c" (string-trim-both " a b c " char-whitespace? 3)) (test-equal "" (string-trim-both " a b c " char? 3)) (test-equal "" (string-trim-both " a b c " char? 0 11)) (test-equal "b c" (string-trim-both " a b c " char-whitespace? 3 11)) (test-equal "" (string-trim-both " a b c " char? 3 11)) (test-equal "" (string-trim-both " a b c " char? 0 8)) (test-equal "b" (string-trim-both " a b c " char-whitespace? 3 8)) (test-equal "" (string-trim-both " a b c " char? 3 8)) (test-equal "" (string-trim "")) (test-equal "a b c " (string-trim " a b c ")) (test-equal "" (string-trim "" char-whitespace?)) (test-equal "a b c " (string-trim " a b c " char-whitespace?)) (test-equal "" (string-trim " a b c " char?)) (test-equal "" (string-trim "" char-whitespace? 0)) (test-equal "a b c " (string-trim " a b c " char-whitespace? 0)) (test-equal "" (string-trim " a b c " char? 0)) (test-equal "b c " (string-trim " a b c " char-whitespace? 3)) (test-equal "" (string-trim " a b c " char? 3)) (test-equal "" (string-trim " a b c " char? 0 11)) (test-equal "b c " (string-trim " a b c " char-whitespace? 3 11)) (test-equal "" (string-trim " a b c " char? 3 11)) (test-equal "" (string-trim " a b c " char? 0 8)) (test-equal "b " (string-trim " a b c " char-whitespace? 3 8)) (test-equal "" (string-trim " a b c " char? 3 8)) (test-equal "" (string-trim-right "")) (test-equal " a b c" (string-trim-right " a b c ")) (test-equal "" (string-trim-right "" char-whitespace?)) (test-equal " a b c" (string-trim-right " a b c " char-whitespace?)) (test-equal "" (string-trim-right " a b c " char?)) (test-equal "" (string-trim-right "" char-whitespace? 0)) (test-equal " a b c" (string-trim-right " a b c " char-whitespace? 0)) (test-equal "" (string-trim-right " a b c " char? 0)) (test-equal " b c" (string-trim-right " a b c " char-whitespace? 3)) (test-equal "" (string-trim-right " a b c " char? 3)) (test-equal "" (string-trim-right " a b c " char? 0 11)) (test-equal " b c" (string-trim-right " a b c " char-whitespace? 3 11)) (test-equal "" (string-trim-right " a b c " char? 3 11)) (test-equal "" (string-trim-right " a b c " char? 0 8)) (test-equal " b" (string-trim-right " a b c " char-whitespace? 3 8)) (test-equal "" (string-trim-right " a b c " char? 3 8)) (test-equal "" (string-trim-both "")) (test-equal "a b c" (string-trim-both " a b c ")) (test-equal "" (string-trim-both "" char-whitespace?)) (test-equal "a b c" (string-trim-both " a b c " char-whitespace?)) (test-equal "" (string-trim-both " a b c " char?)) (test-equal "" (string-trim-both "" char-whitespace? 0)) (test-equal "a b c" (string-trim-both " a b c " char-whitespace? 0)) (test-equal "" (string-trim-both " a b c " char? 0)) (test-equal "b c" (string-trim-both " a b c " char-whitespace? 3)) (test-equal "" (string-trim-both " a b c " char? 3)) (test-equal "" (string-trim-both " a b c " char? 0 11)) (test-equal "b c" (string-trim-both " a b c " char-whitespace? 3 11)) (test-equal "" (string-trim-both " a b c " char? 3 11)) (test-equal "" (string-trim-both " a b c " char? 0 8)) (test-equal "b" (string-trim-both " a b c " char-whitespace? 3 8)) (test-equal "" (string-trim-both " a b c " char? 3 8)) ;;; Replacement (test-equal "It's lots of fun to code it up in Scheme." (string-replace "It's easy to code it up in Scheme." "lots of fun" 5 9)) (test-equal "The miserable perl programmer endured daily ridicule." (string-replace "The TCL programmer endured daily ridicule." "another miserable perl drone" 4 7 8 22)) (test-equal "It's really easy to code it up in Scheme." (string-replace "It's easy to code it up in Scheme." "really " 5 5)) (test-equal "Runs in O(1) time." ; for strings (using sample implementations) (string-replace "Runs in O(n) time." (string #\1) 10 11)) ;;; Comparison ;;; ;;; The comparison tests aren't perfectly black-box because the ;;; specification of these comparison procedures allows them to ;;; use an ordering other than the usual lexicographic ordering. ;;; The sample implementations use lexicographic ordering, however, ;;; and a test program that discourages implementations from using ;;; orderings that differ from the usual on such simple cases is ;;; probably doing a public service. (test-assert (string=? "Strasse" "Strasse")) (test-assert (string=? "Strasse" "Strasse" "Strasse")) (test-equal #f (string? "z" "zz")) (test-equal #t (string>? "z" "Z")) (test-equal #f (string>=? "z" "zz")) (test-equal #t (string>=? "z" "Z")) (test-assert (string>=? "z" "z")) (let* ((w "a") (x "abc") (y "def") (z (string #\a #\b #\c))) (test-equal (string=? x y z) #f) (test-equal (string=? x x z) #t) (test-equal (string=? w x y) #f) (test-equal (string=? y x w) #f) (test-equal (string? x y z) #f) (test-equal (string>? x x z) #f) (test-equal (string>? w x y) #f) (test-equal (string>? y x w) #t) (test-equal (string<=? x y z) #f) (test-equal (string<=? x x z) #t) (test-equal (string<=? w x y) #t) (test-equal (string<=? y x w) #f) (test-equal (string>=? x y z) #f) (test-equal (string>=? x x z) #t) (test-equal (string>=? w x y) #f) (test-equal (string>=? y x w) #t) (test-equal (string=? x x) #t) (test-equal (string=? w x) #f) (test-equal (string=? y x) #f) (test-equal (string? x x) #f) (test-equal (string>? w x) #f) (test-equal (string>? y x) #t) (test-equal (string<=? x x) #t) (test-equal (string<=? w x) #t) (test-equal (string<=? y x) #f) (test-equal (string>=? x x) #t) (test-equal (string>=? w x) #f) (test-equal (string>=? y x) #t) ) (test-equal #t (string-ci? "a" "Z")) (test-equal #f (string-ci>? "A" "z")) (test-equal #t (string-ci>? "Z" "a")) (test-equal #t (string-ci>? "z" "A")) (test-equal #f (string-ci>? "z" "Z")) (test-equal #f (string-ci>? "Z" "z")) (test-equal #t (string-ci=? "z" "Z")) (test-equal #f (string-ci=? "z" "a")) (test-equal #t (string-ci<=? "a" "Z")) (test-equal #t (string-ci<=? "A" "z")) (test-equal #f (string-ci<=? "Z" "a")) (test-equal #f (string-ci<=? "z" "A")) (test-equal #t (string-ci<=? "z" "Z")) (test-equal #t (string-ci<=? "Z" "z")) (test-equal #f (string-ci>=? "a" "Z")) (test-equal #f (string-ci>=? "A" "z")) (test-equal #t (string-ci>=? "Z" "a")) (test-equal #t (string-ci>=? "z" "A")) (test-equal #t (string-ci>=? "z" "Z")) (test-equal #t (string-ci>=? "Z" "z")) ;;; The full-unicode feature doesn't imply full Unicode in strings, ;;; so these tests might fail even in a conforming implementation. ;;; Implementations that support full Unicode strings often have ;;; this feature, however, even though it isn't listed in the R7RS. (cond-expand (full-unicode (test-equal #f (string=? ABCDEF DEFABC)) (test-equal #f (string=? DEFABC ABCDEF)) (test-equal #t (string=? DEFABC DEFABC)) (test-equal #f (string? ABCDEF DEFABC)) (test-equal #f (string>? DEFABC ABCDEF)) (test-equal #f (string>? DEFABC DEFABC)) (test-equal #f (string<=? ABCDEF DEFABC)) (test-equal #t (string<=? DEFABC ABCDEF)) (test-equal #t (string<=? DEFABC DEFABC)) (test-equal #t (string>=? ABCDEF DEFABC)) (test-equal #f (string>=? DEFABC ABCDEF)) (test-equal #t (string>=? DEFABC DEFABC)) (test-equal #f (string=? "Fuss" fuss)) (test-equal #f (string=? "Fuss" "Fuss" fuss)) (test-equal #f (string=? "Fuss" fuss "Fuss")) (test-equal #f (string=? fuss "Fuss" "Fuss")) (test-equal #t (string? "z" (string eszett))) (test-equal #t (string>? (string eszett) "z")) (test-equal #f (string>=? "z" (string eszett))) (test-equal #t (string>=? (string eszett) "z")) (test-assert (string-ci=? fuss "Fuss")) (test-assert (string-ci=? fuss "FUSS")) (test-assert (string-ci=? chaos0 chaos1 chaos2))) (else)) ;;; Prefixes and suffixes (test-equal 0 (string-prefix-length ABC ABCDEF)) (test-equal 0 (string-prefix-length ABCDEF ABC)) (test-equal 0 (string-prefix-length ABCDEF DEFABC)) (test-equal 6 (string-prefix-length DEFABC DEFABC)) (test-equal 0 (string-prefix-length "" "")) (test-equal 0 (string-prefix-length "" "aabbccddee")) (test-equal 0 (string-prefix-length "aisle" "")) (test-equal 0 (string-prefix-length "" "aabbccddee")) (test-equal 1 (string-prefix-length "aisle" "aabbccddee")) (test-equal 0 (string-prefix-length "bail" "aabbccddee")) (test-equal 4 (string-prefix-length "prefix" "preface")) (test-equal 0 (string-prefix-length "" "" 0)) (test-equal 0 (string-prefix-length "" "aabbccddee" 0)) (test-equal 0 (string-prefix-length "aisle" "" 0)) (test-equal 1 (string-prefix-length "aisle" "aabbccddee" 0)) (test-equal 0 (string-prefix-length "bail" "aabbccddee" 0)) (test-equal 4 (string-prefix-length "prefix" "preface" 0)) (test-equal 0 (string-prefix-length "aisle" "" 1)) (test-equal 0 (string-prefix-length "aisle" "aabbccddee" 1)) (test-equal 1 (string-prefix-length "bail" "aabbccddee" 1)) (test-equal 0 (string-prefix-length "prefix" "preface" 1)) (test-equal 0 (string-prefix-length "" "" 0 0)) (test-equal 0 (string-prefix-length "" "aabbccddee" 0 0)) (test-equal 0 (string-prefix-length "aisle" "" 0 4)) (test-equal 1 (string-prefix-length "aisle" "aabbccddee" 0 4)) (test-equal 0 (string-prefix-length "bail" "aabbccddee" 0 1)) (test-equal 0 (string-prefix-length "aisle" "" 1 4)) (test-equal 0 (string-prefix-length "aisle" "aabbccddee" 1 4)) (test-equal 1 (string-prefix-length "bail" "aabbccddee" 1 4)) (test-equal 0 (string-prefix-length "prefix" "preface" 1 5)) (test-equal 0 (string-prefix-length "" "" 0 0 0)) (test-equal 0 (string-prefix-length "" "aabbccddee" 0 0 0)) (test-equal 0 (string-prefix-length "aisle" "" 0 4 0)) (test-equal 0 (string-prefix-length "aisle" "aabbccddee" 0 4 2)) (test-equal 1 (string-prefix-length "bail" "aabbccddee" 0 1 2)) (test-equal 0 (string-prefix-length "prefix" "preface" 0 5 1)) (test-equal 0 (string-prefix-length "aisle" "" 1 4 0)) (test-equal 0 (string-prefix-length "aisle" "aabbccddee" 1 4 3)) (test-equal 0 (string-prefix-length "bail" "aabbccddee" 1 4 3)) (test-equal 3 (string-prefix-length "prefix" "preface" 1 5 1)) (test-equal 0 (string-prefix-length "" "" 0 0 0 0)) (test-equal 0 (string-prefix-length "" "aabbccddee" 0 0 0 0)) (test-equal 0 (string-prefix-length "aisle" "" 0 4 0 0)) (test-equal 0 (string-prefix-length "aisle" "aabbccddee" 0 4 2 10)) (test-equal 1 (string-prefix-length "bail" "aabbccddee" 0 1 2 10)) (test-equal 0 (string-prefix-length "prefix" "preface" 0 5 1 6)) (test-equal 0 (string-prefix-length "aisle" "" 1 4 0 0)) (test-equal 0 (string-prefix-length "aisle" "aabbccddee" 1 4 3 3)) (test-equal 0 (string-prefix-length "bail" "aabbccddee" 1 4 3 6)) (test-equal 3 (string-prefix-length "prefix" "preface" 1 5 1 7)) (test-equal 0 (string-suffix-length ABC ABCDEF)) (test-equal 0 (string-suffix-length ABCDEF ABC)) (test-equal 0 (string-suffix-length ABCDEF DEFABC)) (test-equal 6 (string-suffix-length DEFABC DEFABC)) (test-equal 0 (string-suffix-length "" "")) (test-equal 0 (string-suffix-length "" "aabbccddee")) (test-equal 0 (string-suffix-length "aisle" "")) (test-equal 0 (string-suffix-length "" "aabbccddee")) (test-equal 1 (string-suffix-length "aisle" "aabbccddee")) (test-equal 0 (string-suffix-length "bail" "aabbccddee")) (test-equal 3 (string-suffix-length "place" "preface")) (test-equal 0 (string-suffix-length "" "" 0)) (test-equal 0 (string-suffix-length "" "aabbccddee" 0)) (test-equal 0 (string-suffix-length "aisle" "" 0)) (test-equal 1 (string-suffix-length "aisle" "aabbccddee" 0)) (test-equal 0 (string-suffix-length "bail" "aabbccddee" 0)) (test-equal 3 (string-suffix-length "place" "preface" 0)) (test-equal 0 (string-suffix-length "aisle" "" 1)) (test-equal 1 (string-suffix-length "aisle" "aabbccddee" 1)) (test-equal 0 (string-suffix-length "bail" "aabbccddee" 1)) (test-equal 3 (string-suffix-length "place" "preface" 1)) (test-equal 0 (string-suffix-length "" "" 0 0)) (test-equal 0 (string-suffix-length "" "aabbccddee" 0 0)) (test-equal 0 (string-suffix-length "aisle" "" 0 4)) (test-equal 0 (string-suffix-length "aisle" "aabbccddee" 0 4)) (test-equal 0 (string-suffix-length "bail" "aabbccddee" 0 1)) (test-equal 0 (string-suffix-length "aisle" "" 1 4)) (test-equal 0 (string-suffix-length "aisle" "aabbccddee" 1 4)) (test-equal 1 (string-suffix-length "aisle" "aabbccddee" 1 5)) (test-equal 0 (string-suffix-length "bail" "aabbccddee" 1 4)) (test-equal 3 (string-suffix-length "place" "preface" 1 5)) (test-equal 0 (string-suffix-length "" "" 0 0 0)) (test-equal 0 (string-suffix-length "" "aabbccddee" 0 0 0)) (test-equal 0 (string-suffix-length "aisle" "" 0 4 0)) (test-equal 0 (string-suffix-length "aisle" "aabbccddee" 0 4 2)) (test-equal 0 (string-suffix-length "bail" "aabbccddee" 0 1 2)) (test-equal 3 (string-suffix-length "place" "preface" 0 5 1)) (test-equal 0 (string-suffix-length "aisle" "" 1 4 0)) (test-equal 0 (string-suffix-length "aisle" "aabbccddee" 1 4 3)) (test-equal 0 (string-suffix-length "bail" "aabbccddee" 1 4 3)) (test-equal 3 (string-suffix-length "place" "preface" 1 5 1)) (test-equal 0 (string-suffix-length "" "" 0 0 0 0)) (test-equal 0 (string-suffix-length "" "aabbccddee" 0 0 0 0)) (test-equal 0 (string-suffix-length "aisle" "" 0 4 0 0)) (test-equal 1 (string-suffix-length "aisle" "aabbccddee" 0 5 2 10)) (test-equal 1 (string-suffix-length "bail" "aabbccddee" 0 1 2 4)) (test-equal 0 (string-suffix-length "place" "preface" 0 5 1 6)) (test-equal 2 (string-suffix-length "place" "preface" 0 4 1 6)) (test-equal 0 (string-suffix-length "aisle" "" 1 4 0 0)) (test-equal 0 (string-suffix-length "aisle" "aabbccddee" 1 4 3 3)) (test-equal 0 (string-suffix-length "bail" "aabbccddee" 1 4 3 6)) (test-equal 3 (string-suffix-length "place" "preface" 1 5 1 7)) (test-equal #f (string-prefix? ABC ABCDEF)) (test-equal #f (string-prefix? ABCDEF ABC)) (test-equal #f (string-prefix? ABCDEF DEFABC)) (test-equal #t (string-prefix? DEFABC DEFABC)) (test-equal #t (string-prefix? "" "")) (test-equal #t (string-prefix? "" "abc")) (test-equal #t (string-prefix? "a" "abc")) (test-equal #f (string-prefix? "c" "abc")) (test-equal #t (string-prefix? "ab" "abc")) (test-equal #f (string-prefix? "ac" "abc")) (test-equal #t (string-prefix? "abc" "abc")) (test-equal #f (string-suffix? ABC ABCDEF)) (test-equal #f (string-suffix? ABCDEF ABC)) (test-equal #f (string-suffix? ABCDEF DEFABC)) (test-equal #t (string-suffix? DEFABC DEFABC)) (test-equal #t (string-suffix? "" "")) (test-equal #t (string-suffix? "" "abc")) (test-equal #f (string-suffix? "a" "abc")) (test-equal #t (string-suffix? "c" "abc")) (test-equal #f (string-suffix? "ac" "abc")) (test-equal #t (string-suffix? "bc" "abc")) (test-equal #t (string-suffix? "abc" "abc")) (test-equal #t (string-prefix? "" "" 0)) (test-equal #t (string-prefix? "" "abc" 0)) (test-equal #t (string-prefix? "a" "abc" 0)) (test-equal #f (string-prefix? "c" "abc" 0)) (test-equal #t (string-prefix? "ab" "abc" 0)) (test-equal #f (string-prefix? "ac" "abc" 0)) (test-equal #t (string-prefix? "abc" "abc" 0)) (test-equal #t (string-suffix? "" "" 0)) (test-equal #t (string-suffix? "" "abc" 0)) (test-equal #f (string-suffix? "a" "abc" 0)) (test-equal #t (string-suffix? "c" "abc" 0)) (test-equal #f (string-suffix? "ac" "abc" 0)) (test-equal #t (string-suffix? "bc" "abc" 0)) (test-equal #t (string-suffix? "abc" "abc" 0)) (test-equal #t (string-prefix? "ab" "abc" 2)) (test-equal #t (string-prefix? "ac" "abc" 2)) (test-equal #f (string-prefix? "abc" "abc" 2)) (test-equal #t (string-suffix? "ac" "abc" 2)) (test-equal #t (string-suffix? "bc" "abc" 2)) (test-equal #t (string-suffix? "abc" "abc" 2)) (test-equal #t (string-prefix? "" "" 0 0)) (test-equal #t (string-prefix? "" "abc" 0 0)) (test-equal #t (string-prefix? "a" "abc" 0 0)) (test-equal #f (string-prefix? "c" "abc" 0 1)) (test-equal #t (string-prefix? "ab" "abc" 0 1)) (test-equal #t (string-prefix? "ab" "abc" 0 2)) (test-equal #f (string-prefix? "ac" "abc" 0 2)) (test-equal #t (string-prefix? "abc" "abc" 0 3)) (test-equal #t (string-suffix? "" "" 0 0)) (test-equal #t (string-suffix? "" "abc" 0 0)) (test-equal #f (string-suffix? "a" "abc" 0 1)) (test-equal #t (string-suffix? "c" "abc" 0 1)) (test-equal #t (string-suffix? "ac" "abc" 1 2)) (test-equal #f (string-suffix? "ac" "abc" 0 2)) (test-equal #t (string-suffix? "bc" "abc" 0 2)) (test-equal #t (string-suffix? "abc" "abc" 0 3)) (test-equal #t (string-prefix? "ab" "abc" 2 2)) (test-equal #t (string-prefix? "ac" "abc" 2 2)) (test-equal #f (string-prefix? "abc" "abc" 2 3)) (test-equal #t (string-suffix? "ac" "abc" 2 2)) (test-equal #t (string-suffix? "bc" "abc" 2 2)) (test-equal #t (string-suffix? "abc" "abc" 2 3)) (test-equal #t (string-prefix? "" "" 0 0 0)) (test-equal #t (string-prefix? "" "abc" 0 0 0)) (test-equal #t (string-prefix? "a" "abc" 0 0 0)) (test-equal #f (string-prefix? "c" "abc" 0 1 0)) (test-equal #t (string-prefix? "ab" "abc" 0 1 0)) (test-equal #t (string-prefix? "ab" "abc" 0 2 0)) (test-equal #f (string-prefix? "ac" "abc" 0 2 0)) (test-equal #t (string-prefix? "abc" "abc" 0 3 0)) (test-equal #t (string-suffix? "" "" 0 0 0)) (test-equal #t (string-suffix? "" "abc" 0 0 0)) (test-equal #f (string-suffix? "a" "abc" 0 1 0)) (test-equal #t (string-suffix? "c" "abc" 0 1 0)) (test-equal #t (string-suffix? "ac" "abc" 1 2 0)) (test-equal #f (string-suffix? "ac" "abc" 0 2 0)) (test-equal #t (string-suffix? "bc" "abc" 0 2 0)) (test-equal #t (string-suffix? "abc" "abc" 0 3 0)) (test-equal #t (string-prefix? "ab" "abc" 2 2 0)) (test-equal #t (string-prefix? "ac" "abc" 2 2 0)) (test-equal #f (string-prefix? "abc" "abc" 2 3 0)) (test-equal #t (string-suffix? "ac" "abc" 2 2 0)) (test-equal #t (string-suffix? "bc" "abc" 2 2 0)) (test-equal #t (string-suffix? "abc" "abc" 2 3 0)) (test-equal #t (string-prefix? "" "abc" 0 0 1)) (test-equal #t (string-prefix? "a" "abc" 0 0 1)) (test-equal #t (string-prefix? "c" "abc" 0 1 2)) (test-equal #f (string-prefix? "ab" "abc" 0 1 2)) (test-equal #f (string-prefix? "ab" "abc" 0 2 1)) (test-equal #f (string-prefix? "ac" "abc" 0 2 1)) (test-equal #f (string-prefix? "abc" "abc" 0 3 1)) (test-equal #f (string-suffix? "a" "abc" 0 1 2)) (test-equal #t (string-suffix? "c" "abc" 0 1 1)) (test-equal #t (string-suffix? "ac" "abc" 1 2 2)) (test-equal #t (string-suffix? "bc" "abc" 0 2 1)) (test-equal #f (string-suffix? "bc" "abc" 0 2 2)) (test-equal #t (string-prefix? "" "" 0 0 0 0)) (test-equal #t (string-prefix? "" "abc" 0 0 0 3)) (test-equal #t (string-prefix? "a" "abc" 0 0 0 3)) (test-equal #f (string-prefix? "c" "abc" 0 1 0 3)) (test-equal #t (string-prefix? "ab" "abc" 0 1 0 3)) (test-equal #t (string-prefix? "ab" "abc" 0 2 0 3)) (test-equal #f (string-prefix? "ac" "abc" 0 2 0 3)) (test-equal #t (string-prefix? "abc" "abc" 0 3 0 3)) (test-equal #t (string-suffix? "" "abc" 0 0 0 3)) (test-equal #f (string-suffix? "a" "abc" 0 1 0 3)) (test-equal #t (string-suffix? "c" "abc" 0 1 0 3)) (test-equal #t (string-suffix? "ac" "abc" 1 2 0 3)) (test-equal #f (string-suffix? "ac" "abc" 0 2 0 3)) (test-equal #t (string-suffix? "bc" "abc" 0 2 0 3)) (test-equal #t (string-suffix? "abc" "abc" 0 3 0 3)) (test-equal #t (string-prefix? "ab" "abc" 2 2 0 3)) (test-equal #t (string-prefix? "ac" "abc" 2 2 0 3)) (test-equal #f (string-prefix? "abc" "abc" 2 3 0 3)) (test-equal #t (string-suffix? "ac" "abc" 2 2 0 3)) (test-equal #t (string-suffix? "bc" "abc" 2 2 0 3)) (test-equal #t (string-suffix? "abc" "abc" 2 3 0 3)) (test-equal #t (string-prefix? "" "abc" 0 0 1 3)) (test-equal #t (string-prefix? "a" "abc" 0 0 1 3)) (test-equal #t (string-prefix? "c" "abc" 0 1 2 3)) (test-equal #f (string-prefix? "ab" "abc" 0 1 2 3)) (test-equal #f (string-prefix? "ab" "abc" 0 2 1 3)) (test-equal #f (string-prefix? "ac" "abc" 0 2 1 3)) (test-equal #f (string-prefix? "abc" "abc" 0 3 1 3)) (test-equal #f (string-suffix? "a" "abc" 0 1 2 3)) (test-equal #t (string-suffix? "c" "abc" 0 1 1 3)) (test-equal #t (string-suffix? "ac" "abc" 1 2 2 3)) (test-equal #t (string-suffix? "bc" "abc" 0 2 1 3)) (test-equal #f (string-suffix? "bc" "abc" 0 2 2 3)) (test-equal #t (string-prefix? "" "abc" 0 0 0 2)) (test-equal #t (string-prefix? "a" "abc" 0 0 0 2)) (test-equal #f (string-prefix? "c" "abc" 0 1 0 2)) (test-equal #t (string-prefix? "ab" "abc" 0 1 0 2)) (test-equal #f (string-prefix? "abc" "abc" 0 3 0 2)) (test-equal #t (string-suffix? "" "abc" 0 0 0 2)) (test-equal #f (string-suffix? "c" "abc" 0 1 0 2)) (test-equal #f (string-suffix? "ac" "abc" 1 2 0 2)) ;;; Searching (test-equal #f (string-index "" char?)) (test-equal 0 (string-index "abcdef" char?)) (test-equal 4 (string-index "abcdef" (lambda (c) (char>? c #\d)))) (test-equal #f (string-index "abcdef" char-whitespace?)) (test-equal #f (string-index-right "" char?)) (test-equal 5 (string-index-right "abcdef" char?)) (test-equal 5 (string-index-right "abcdef" (lambda (c) (char>? c #\d)))) (test-equal #f (string-index-right "abcdef" char-whitespace?)) (test-equal #f (string-skip "" string?)) (test-equal 0 (string-skip "abcdef" string?)) (test-equal 4 (string-skip "abcdef" (lambda (c) (char<=? c #\d)))) (test-equal #f (string-skip "abcdef" char?)) (test-equal #f (string-skip-right "" string?)) (test-equal 5 (string-skip-right "abcdef" string?)) (test-equal 5 (string-skip-right "abcdef" (lambda (c) (char<=? c #\d)))) (test-equal #f (string-skip-right "abcdef" char?)) (test-equal 2 (string-index "abcdef" char? 2)) (test-equal 4 (string-index "abcdef" (lambda (c) (char>? c #\d)) 2)) (test-equal #f (string-index "abcdef" char-whitespace? 2)) (test-equal 5 (string-index-right "abcdef" char? 2)) (test-equal 5 (string-index-right "abcdef" (lambda (c) (char>? c #\d)) 2)) (test-equal #f (string-index-right "abcdef" char-whitespace? 2)) (test-equal 2 (string-skip "abcdef" string? 2)) (test-equal 4 (string-skip "abcdef" (lambda (c) (char<=? c #\d)) 2)) (test-equal #f (string-skip "abcdef" char? 2)) (test-equal 5 (string-skip-right "abcdef" string? 2)) (test-equal 5 (string-skip-right "abcdef" (lambda (c) (char<=? c #\d)) 2)) (test-equal #f (string-skip-right "abcdef" char? 2)) (test-equal 2 (string-index "abcdef" char? 2 5)) (test-equal 4 (string-index "abcdef" (lambda (c) (char>? c #\d)) 2 5)) (test-equal #f (string-index "abcdef" char-whitespace? 2 5)) (test-equal 4 (string-index-right "abcdef" char? 2 5)) (test-equal 4 (string-index-right "abcdef" (lambda (c) (char>? c #\d)) 2 5)) (test-equal #f (string-index-right "abcdef" char-whitespace? 2 5)) (test-equal 2 (string-skip "abcdef" string? 2 5)) (test-equal 4 (string-skip "abcdef" (lambda (c) (char<=? c #\d)) 2 5)) (test-equal #f (string-skip "abcdef" char? 2 5)) (test-equal 4 (string-skip-right "abcdef" string? 2 5)) (test-equal 4 (string-skip-right "abcdef" (lambda (c) (char<=? c #\d)) 2 5)) (test-equal #f (string-skip-right "abcdef" char? 2 5)) (test-equal 0 (string-contains "" "")) (test-equal 0 (string-contains "abcdeffffoo" "")) (test-equal 0 (string-contains "abcdeffffoo" "a")) (test-equal 5 (string-contains "abcdeffffoo" "ff")) (test-equal 4 (string-contains "abcdeffffoo" "eff")) (test-equal 8 (string-contains "abcdeffffoo" "foo")) (test-equal #f (string-contains "abcdeffffoo" "efffoo")) (test-equal 0 (string-contains-right "" "")) (test-equal 11 (string-contains-right "abcdeffffoo" "")) (test-equal 0 (string-contains-right "abcdeffffoo" "a")) (test-equal 7 (string-contains-right "abcdeffffoo" "ff")) (test-equal 4 (string-contains-right "abcdeffffoo" "eff")) (test-equal 8 (string-contains-right "abcdeffffoo" "foo")) (test-equal #f (string-contains-right "abcdeffffoo" "efffoo")) (test-equal 0 (string-contains "" "" 0)) (test-equal 2 (string-contains "abcdeffffoo" "" 2)) (test-equal #f (string-contains "abcdeffffoo" "a" 2)) (test-equal 5 (string-contains "abcdeffffoo" "ff" 2)) (test-equal 4 (string-contains "abcdeffffoo" "eff" 2)) (test-equal 8 (string-contains "abcdeffffoo" "foo" 2)) (test-equal #f (string-contains "abcdeffffoo" "efffoo" 2)) (test-equal 0 (string-contains-right "" "" 0)) (test-equal 11 (string-contains-right "abcdeffffoo" "" 2)) (test-equal #f (string-contains-right "abcdeffffoo" "a" 2)) (test-equal 7 (string-contains-right "abcdeffffoo" "ff" 2)) (test-equal 4 (string-contains-right "abcdeffffoo" "eff" 2)) (test-equal 8 (string-contains-right "abcdeffffoo" "foo" 2)) (test-equal #f (string-contains-right "abcdeffffoo" "efffoo" 2)) (test-equal 0 (string-contains "" "" 0 0)) (test-equal 2 (string-contains "abcdeffffoo" "" 2 10)) (test-equal #f (string-contains "abcdeffffoo" "a" 2 10)) (test-equal 5 (string-contains "abcdeffffoo" "ff" 2 10)) (test-equal 4 (string-contains "abcdeffffoo" "eff" 2 10)) (test-equal #f (string-contains "abcdeffffoo" "foo" 2 10)) (test-equal #f (string-contains "abcdeffffoo" "efffoo" 2 10)) (test-equal 0 (string-contains-right "" "" 0 0)) (test-equal 10 (string-contains-right "abcdeffffoo" "" 2 10)) (test-equal #f (string-contains-right "abcdeffffoo" "a" 2 10)) (test-equal 7 (string-contains-right "abcdeffffoo" "ff" 2 10)) (test-equal 4 (string-contains-right "abcdeffffoo" "eff" 2 10)) (test-equal #f (string-contains-right "abcdeffffoo" "foo" 2 10)) (test-equal #f (string-contains-right "abcdeffffoo" "efffoo" 2 10)) (test-equal 0 (string-contains "" "" 0 0 0)) (test-equal 2 (string-contains "abcdeffffoo" "" 2 10 0)) (test-equal 2 (string-contains "abcdeffffoo" "a" 2 10 1)) (test-equal 5 (string-contains "abcdeffffoo" "ff" 2 10 1)) (test-equal 5 (string-contains "abcdeffffoo" "eff" 2 10 1)) (test-equal #f (string-contains "abcdeffffoo" "foo" 2 10 1)) (test-equal #f (string-contains "abcdeffffoo" "efffoo" 2 10 1)) (test-equal 0 (string-contains-right "" "" 0 0 0)) (test-equal 10 (string-contains-right "abcdeffffoo" "" 2 10 0)) (test-equal 10 (string-contains-right "abcdeffffoo" "a" 2 10 1)) (test-equal 8 (string-contains-right "abcdeffffoo" "ff" 2 10 1)) (test-equal 7 (string-contains-right "abcdeffffoo" "eff" 2 10 1)) (test-equal #f (string-contains-right "abcdeffffoo" "foo" 2 10 1)) (test-equal #f (string-contains-right "abcdeffffoo" "efffoo" 2 10 1)) (test-equal 0 (string-contains "" "" 0 0 0 0)) (test-equal 2 (string-contains "abcdeffffoo" "" 2 10 0 0)) (test-equal 2 (string-contains "abcdeffffoo" "a" 2 10 1 1)) (test-equal 5 (string-contains "abcdeffffoo" "ff" 2 10 1 2)) (test-equal 5 (string-contains "abcdeffffoo" "eff" 2 10 1 2)) (test-equal 9 (string-contains "abcdeffffoo" "foo" 2 10 1 2)) (test-equal 4 (string-contains "abcdeffffoo" "efffoo" 2 10 0 2)) (test-equal 0 (string-contains-right "" "" 0 0 0 0)) (test-equal 10 (string-contains-right "abcdeffffoo" "" 2 10 0 0)) (test-equal 10 (string-contains-right "abcdeffffoo" "a" 2 10 1 1)) (test-equal 8 (string-contains-right "abcdeffffoo" "ff" 2 10 1 2)) (test-equal 8 (string-contains-right "abcdeffffoo" "eff" 2 10 1 2)) (test-equal 9 (string-contains-right "abcdeffffoo" "foo" 2 10 1 2)) (test-equal 7 (string-contains-right "abcdeffffoo" "efffoo" 2 10 1 3)) ;;; Case conversion ;;; FIXME: should test some non-ASCII cases here. (test-equal "1234STRIKES" (string-upcase "1234Strikes")) (test-equal "1234STRIKES" (string-upcase "1234strikes")) (test-equal "1234STRIKES" (string-upcase "1234STRIKES")) (test-equal "1234strikes" (string-downcase "1234Strikes")) (test-equal "1234strikes" (string-downcase "1234strikes")) (test-equal "1234strikes" (string-downcase "1234STRIKES")) (test-equal "1234strikes" (string-foldcase "1234Strikes")) (test-equal "1234strikes" (string-foldcase "1234strikes")) (test-equal "1234strikes" (string-foldcase "1234STRIKES")) (test-equal "And With Three Strikes You Are Out" (string-titlecase "and with THREE STRIKES you are oUT")) ;;; Concatenation (test-equal "" (string-append)) (test-equal "abcdef" (string-append "" "a" "bcd" "" "ef" "" "")) (test-equal "" (string-concatenate '())) (test-equal "abcdef" (string-concatenate '("" "a" "bcd" "" "ef" "" ""))) ;;; string-concatenate is likely to have special cases for longer strings. (let* ((alphabet "abcdefghijklmnopqrstuvwxyz") (str1 alphabet) (str10 (apply string-append (vector->list (make-vector 10 str1)))) (str100 (apply string-append (vector->list (make-vector 10 str10)))) (str100-500 (substring str100 100 500)) (str600-999 (substring str100 600 999)) (alph1 (string-copy alphabet)) (alph10 (string-concatenate (vector->list (make-vector 10 alph1)))) (alph100 (string-concatenate (vector->list (make-vector 10 alph10)))) (t100-500 (substring alph100 100 500)) (t600-999 (substring alph100 600 999))) (test-equal str10 alph10) (test-equal str100 alph100) (test-equal str100-500 t100-500) (test-equal str600-999 t600-999) ;; concatenating a short string with a long string (test-equal (string-append str1 str600-999) (string-concatenate (list alph1 t600-999))) (test-equal (string-append str1 str600-999) (string-concatenate (list alph1 (string-copy t600-999)))) (test-equal (string-append str600-999 str1) (string-concatenate (list t600-999 alph1))) (test-equal (string-append str600-999 str1) (string-concatenate (list (string-copy t600-999) alph1)))) (test-equal "" (string-concatenate-reverse '())) (test-equal "efbcda" (string-concatenate-reverse '("" "a" "bcd" "" "ef" "" ""))) (test-equal "huh?" (string-concatenate-reverse '() "huh?")) (test-equal "efbcdaxy" (string-concatenate-reverse '("" "a" "bcd" "" "ef" "" "") "xy")) (test-equal "huh" (string-concatenate-reverse '() "huh?" 3)) (test-equal "efbcdax" (string-concatenate-reverse '("" "a" "bcd" "" "ef" "" "") "x" 1)) (test-equal "" (string-join '())) (test-equal " ab cd e f " (string-join '("" "ab" "cd" "" "e" "f" ""))) (test-equal "" (string-join '() "")) (test-equal "abcdef" (string-join '("" "ab" "cd" "" "e" "f" "") "")) (test-equal "" (string-join '() "xyz")) (test-equal "xyzabxyzcdxyzxyzexyzfxyz" (string-join '("" "ab" "cd" "" "e" "f" "") "xyz")) (test-equal "" (string-join '() "" 'infix)) (test-equal "abcdef" (string-join '("" "ab" "cd" "" "e" "f" "") "" 'infix)) (test-equal "" (string-join '() "xyz" 'infix)) (test-equal "xyzabxyzcdxyzxyzexyzfxyz" (string-join '("" "ab" "cd" "" "e" "f" "") "xyz" 'infix)) (test-equal "foo bar baz" (string-join '("foo" "bar" "baz"))) (test-equal "foobarbaz" (string-join '("foo" "bar" "baz") "")) (test-equal "foo:bar:baz" (string-join '("foo" "bar" "baz") ":")) (test-equal "foo:bar:baz:" (string-join '("foo" "bar" "baz") ":" 'suffix)) (test-equal "" (string-join '() ":")) (test-equal "" (string-join '("") ":")) (test-equal "" (string-join '() ":" 'infix)) (test-error (string-join '() ":" 'strict-infix)) (test-equal "A" (string-join '("A") ":" 'strict-infix)) (test-equal "A:B" (string-join '("A" "B") ":" 'strict-infix)) (test-equal "" (string-join '() ":" 'suffix)) (test-equal ":" (string-join '("") ":" 'suffix)) (test-equal 'horror (guard (exn (#t 'horror)) (string-join '() "" 'strict-infix))) (test-equal "abcdef" (string-join '("" "ab" "cd" "" "e" "f" "") "" 'strict-infix)) (test-equal 'wham (guard (exn (else 'wham)) (string-join '() "xyz" 'strict-infix))) (test-equal "xyzabxyzcdxyzxyzexyzfxyz" (string-join '("" "ab" "cd" "" "e" "f" "") "xyz" 'strict-infix)) (test-equal "" (string-join '() "" 'suffix)) (test-equal "abcdef" (string-join '("" "ab" "cd" "" "e" "f" "") "" 'suffix)) (test-equal "" (string-join '() "xyz" 'suffix)) (test-equal "xyzabxyzcdxyzxyzexyzfxyzxyz" (string-join '("" "ab" "cd" "" "e" "f" "") "xyz" 'suffix)) (test-equal "" (string-join '() "" 'prefix)) (test-equal "abcdef" (string-join '("" "ab" "cd" "" "e" "f" "") "" 'prefix)) (test-equal "" (string-join '() "xyz" 'prefix)) (test-equal "xyzxyzabxyzcdxyzxyzexyzfxyz" (string-join '("" "ab" "cd" "" "e" "f" "") "xyz" 'prefix)) ;;; Fold & map & friends (test-equal 8 (string-fold (lambda (c count) (if (char-whitespace? c) (+ count 1) count)) 0 " ...a couple of spaces in this one... ")) (test-equal 7 (string-fold (lambda (c count) (if (char-whitespace? c) (+ count 1) count)) 0 " ...a couple of spaces in this one... " 1)) (test-equal 6 (string-fold (lambda (c count) (if (char-whitespace? c) (+ count 1) count)) 0 " ...a couple of spaces in this one... " 1 32)) (test-equal (string->list "abcdef") (string-fold-right cons '() "abcdef")) (test-equal (string->list "def") (string-fold-right cons '() "abcdef" 3)) (test-equal (string->list "cde") (string-fold-right cons '() "abcdef" 2 5)) (test-equal "aabraacaadaabraa" (let* ((s "abracadabra") (ans-len (string-fold (lambda (c sum) (+ sum (if (char=? c #\a) 2 1))) 0 s)) (ans (make-string ans-len))) (string-fold (lambda (c i) (let ((i (if (char=? c #\a) (begin (string-set! ans i #\a) (+ i 1)) i))) (string-set! ans i c) (+ i 1))) 0 s) ans)) (test-equal "abc" (string-map string "abc")) (test-equal "ABC" (string-map char-upcase "abc")) (test-equal "Hear-here!" (string-map (lambda (c0 c1 c2) (case c0 ((#\1) c1) ((#\2) (string c2)) ((#\-) (string #\- c1)))) "1222-1111-2222" "Hi There!" "Dear John")) (test-equal "abc" (let ((q (open-output-string))) (string-for-each (lambda (c) (write-char c q)) "abc") (get-output-string q))) (test-equal '("cfi" "beh" "adg") (let ((x '())) (string-for-each (lambda (c1 c2 c3) (set! x (cons (string c1 c2 c3) x))) "abc" "defxyz" "ghijklmnopqrstuvwxyz") x)) (test-equal "abc" (string-map-index (lambda (i) (integer->char (+ i (char->integer #\a)))) "xyz")) (let ((r (string-map-index (lambda (i) (integer->char (+ i (char->integer #\a)))) "xyz***" 3))) (test-equal '(#t 3) (check-istring r)) (test-equal "def" r)) (test-equal "cde" (string-map-index (lambda (i) (integer->char (+ i (char->integer #\a)))) "......" 2 5)) (test-equal '(101 100 99 98 97) (let ((s "abcde") (v '())) (string-for-each-index (lambda (i) (set! v (cons (char->integer (string-ref s i)) v))) s) v)) (test-equal '(101 100 99) (let ((s "abcde") (v '())) (string-for-each-index (lambda (i) (set! v (cons (char->integer (string-ref s i)) v))) s 2) v)) (test-equal '(99 98) (let ((s "abcde") (v '())) (string-for-each-index (lambda (i) (set! v (cons (char->integer (string-ref s i)) v))) s 1 3) v)) (test-equal 6 (string-count "abcdef" char?)) (test-equal 4 (string-count "counting whitespace, again " char-whitespace? 5)) (test-equal 3 (string-count "abcdefwxyz" (lambda (c) (odd? (char->integer c))) 2 8)) (let ((r (string-filter (lambda (c) (memv c (string->list "aeiou"))) "What is number, that man may know it?"))) (test-equal "aiueaaaoi" r) (test-equal '(#t 9) (check-istring r))) (let ((r (string-remove (lambda (c) (memv c (string->list "aeiou"))) "And woman, that she may know number?"))) (test-equal "And wmn, tht sh my knw nmbr?" r) (test-equal '(#t 28) (check-istring r))) (test-equal "iueaaaoi" (string-filter (lambda (c) (memv c (string->list "aeiou"))) "What is number, that man may know it?" 4)) (test-equal "mn, tht sh my knw nmbr?" (string-remove (lambda (c) (memv c (string->list "aeiou"))) "And woman, that she may know number?" 6)) (test-equal "aaao" (string-filter (lambda (c) (memv c (string->list "aeiou"))) "What is number, that man may know it?" 16 32)) (test-equal "And woman, that sh may know" (string-remove (lambda (c) (memv c (string->list "eiu"))) "And woman, that she may know number?" 0 28)) #| (test-equal "" (string-reverse "")) (test-equal "fedcba" (string-reverse "abcdef")) (test-equal "" (string-reverse "" 0)) (test-equal "fedcba" (string-reverse "abcdef" 0)) (test-equal "fedc" (string-reverse "abcdef" 2)) (test-equal "" (string-reverse "" 0 0)) (test-equal "fedcba" (string-reverse "abcdef" 0 6)) (test-equal "edc" (string-reverse "abcdef" 2 5)) |# ;;; Replication and splitting (test-equal "" (string-repeat #\X 0)) (test-equal "XXX" (string-repeat #\X 3)) (test-equal "" (string-repeat "abc" 0)) (test-equal "abcabcabc" (string-repeat "abc" 3)) (test-equal "cdefabcdefabcd" (xsubstring "abcdef" -4 10)) (test-equal "bcdefbcdefbcd" (xsubstring "abcdef" 90 103 1)) (test-equal "ecdecdecde" (xsubstring "abcdef" -13 -3 2 5)) (test-equal "cdefab" (xsubstring "abcdef" 2 8)) (test-equal "efabcd" (xsubstring "abcdef" -2 4)) (test-equal "abcabca" (xsubstring "abc" 0 7)) (test-equal '() (string-split "" "")) (test-equal '("a" "b" "c") (string-split "abc" "")) (test-equal '("too" "" "much" "" "data") (string-split "too much data" " ")) (test-equal '("" "there" "ya" "go" "") (string-split "***there***ya***go***" "***")) (test-equal '() (string-split "" "" 'infix)) (test-equal '("a" "b" "c") (string-split "abc" "" 'infix)) (test-equal '("too" "" "much" "" "data") (string-split "too much data" " " 'infix)) (test-equal '("" "there" "ya" "go" "") (string-split "***there***ya***go***" "***" 'infix)) (test-equal 'error (guard (exn (else 'error)) (string-split "" "" 'strict-infix))) (test-equal '("a" "b" "c") (string-split "abc" "" 'strict-infix)) (test-equal '("too" "" "much" "" "data") (string-split "too much data" " " 'strict-infix)) (test-equal '("" "there" "ya" "go" "") (string-split "***there***ya***go***" "***" 'strict-infix)) (test-equal '() (string-split "" "" 'prefix)) (test-equal '("a" "b" "c") (string-split "abc" "" 'prefix)) (test-equal '("too" "" "much" "" "data") (string-split "too much data" " " 'prefix)) (test-equal '("there" "ya" "go" "") (string-split "***there***ya***go***" "***" 'prefix)) (test-equal '() (string-split "" "" 'suffix)) (test-equal '("a" "b" "c") (string-split "abc" "" 'suffix)) (test-equal '("too" "" "much" "" "data") (string-split "too much data" " " 'suffix)) (test-equal '("" "there" "ya" "go") (string-split "***there***ya***go***" "***" 'suffix)) (test-equal '() (string-split "" "" 'infix #f)) (test-equal '("a" "b" "c") (string-split "abc" "" 'infix #f)) (test-equal '("too" "" "much" "" "data") (string-split "too much data" " " 'infix #f)) (test-equal '("" "there" "ya" "go" "") (string-split "***there***ya***go***" "***" 'infix #f)) (test-equal 'error (guard (exn (else 'error)) (string-split "" "" 'strict-infix #f))) (test-equal '("a" "b" "c") (string-split "abc" "" 'strict-infix #f)) (test-equal '("too" "" "much" "" "data") (string-split "too much data" " " 'strict-infix #f)) (test-equal '("" "there" "ya" "go" "") (string-split "***there***ya***go***" "***" 'strict-infix #f)) (test-equal '() (string-split "" "" 'prefix #f)) (test-equal '("a" "b" "c") (string-split "abc" "" 'prefix #f)) (test-equal '("too" "" "much" "" "data") (string-split "too much data" " " 'prefix #f)) (test-equal '("there" "ya" "go" "") (string-split "***there***ya***go***" "***" 'prefix #f)) (test-equal '() (string-split "" "" 'suffix #f)) (test-equal '("a" "b" "c") (string-split "abc" "" 'suffix #f)) (test-equal '("too" "" "much" "" "data") (string-split "too much data" " " 'suffix #f)) (test-equal '("" "there" "ya" "go") (string-split "***there***ya***go***" "***" 'suffix #f)) (test-equal 'error (guard (exn (else 'error)) (string-split "" "" 'strict-infix 3))) (test-equal '("a" "b" "c") (string-split "abc" "" 'strict-infix 3)) (test-equal '("too" "" "much" " data") (string-split "too much data" " " 'strict-infix 3)) (test-equal '("" "there" "ya" "go***") (string-split "***there***ya***go***" "***" 'strict-infix 3)) (test-equal '() (string-split "" "" 'prefix 3)) (test-equal '("a" "b" "c") (string-split "abc" "" 'prefix 3)) (test-equal '("too" "" "much" " data") (string-split "too much data" " " 'prefix 3)) (test-equal '("there" "ya" "go***") (string-split "***there***ya***go***" "***" 'prefix 3)) (test-equal '() (string-split "" "" 'suffix 3)) (test-equal '("a" "b" "c") (string-split "abc" "" 'suffix 3)) (test-equal '("too" "" "much" " data") (string-split "too much data" " " 'suffix 3)) (test-equal '("" "there" "ya" "go***") (string-split "***there***ya***go***" "***" 'suffix 3)) (test-equal 'error (guard (exn (else 'error)) (string-split "" "" 'strict-infix 3 0))) (test-equal '("b" "c") (string-split "abc" "" 'strict-infix 3 1)) (test-equal '("oo" "" "much" " data") (string-split "too much data" " " 'strict-infix 3 1)) (test-equal '("**there" "ya" "go" "") (string-split "***there***ya***go***" "***" 'strict-infix 3 1)) (test-equal '() (string-split "" "" 'prefix 3 0)) (test-equal '("b" "c") (string-split "abc" "" 'prefix 3 1)) (test-equal '("oo" "" "much" " data") (string-split "too much data" " " 'prefix 3 1)) (test-equal '("**there" "ya" "go" "") (string-split "***there***ya***go***" "***" 'prefix 3 1)) (test-equal '() (string-split "" "" 'suffix 3 0)) (test-equal '("b" "c") (string-split "abc" "" 'suffix 3 1)) (test-equal '("oo" "" "much" " data") (string-split "too much data" " " 'suffix 3 1)) (test-equal '("**there" "ya" "go") (string-split "***there***ya***go***" "***" 'suffix 3 1)) (test-equal 'error (guard (exn (else 'error)) (string-split "" "" 'strict-infix 3 0 0))) (test-equal '("b") (string-split "abc" "" 'strict-infix 3 1 2)) (test-equal '("oo" "" "much" " ") (string-split "too much data" " " 'strict-infix 3 1 11)) (test-equal '() (string-split "" "" 'prefix 3 0 0)) (test-equal '("b") (string-split "abc" "" 'prefix 3 1 2)) (test-equal '("oo" "" "much" " ") (string-split "too much data" " " 'prefix 3 1 11)) (test-equal '() (string-split "" "" 'suffix 3 0 0)) (test-equal '("b") (string-split "abc" "" 'suffix 3 1 2)) (test-equal '("oo" "" "much" " ") (string-split "too much data" " " 'suffix 3 1 11)) (define (translate-space-to-newline str) (let ((result (make-string 0))) (string-for-each (lambda (ch) (string-append! result (if (char=? ch #\space) #\newline ch))) str) result)) (test-equal "ab\ncd\nx" (translate-space-to-newline "ab cd x")) ;; begin section with UTF-8 literals (cond-expand (full-unicode (let ((str (make-string 3 #\😂))) (test-equal 3 (string-length str)) ;; (test-equal 6 (str:length)) (string-replace! str 1 2 "abc") (test-equal "😂abc😂" str) (string-replace! str 5 5 str 3) (test-equal "😂abc😂c😂" str) (string-replace! str 0 2 "ABC" 1 2) (test-equal "Bbc😂c😂" str) (test-equal 6 (string-length str)) (test-equal #\c (string-ref str 2)) (test-equal #\x1f602 (string-ref str 3)) (test-equal #\c (string-ref str 4))) (test-equal "c😼b😂a" (reverse-list->string '(#\a #\😂 #\b #\😼 #\c))) (test-equal "y😂a😼xy" (xsubstring "a😼xy😂" 3 9)) (test-equal "y😂a😼" (xsubstring "a😼xy😂" -2 2)) )) ;; end section with UTF-8 literals (test-end)