Commit | Line | Data |
---|---|---|
0d572e91 | 1 | ;;;; ports.test --- test suite for Guile I/O ports -*- scheme -*- |
000ee07f JB |
2 | ;;;; Jim Blandy <jimb@red-bean.com> --- October 1998 |
3 | ;;;; | |
4 | ;;;; Copyright (C) 1999 Free Software Foundation, Inc. | |
5 | ;;;; | |
6 | ;;;; This program is free software; you can redistribute it and/or modify | |
7 | ;;;; it under the terms of the GNU General Public License as published by | |
8 | ;;;; the Free Software Foundation; either version 2, or (at your option) | |
9 | ;;;; any later version. | |
10 | ;;;; | |
11 | ;;;; This program is distributed in the hope that it will be useful, | |
12 | ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | ;;;; GNU General Public License for more details. | |
15 | ;;;; | |
16 | ;;;; You should have received a copy of the GNU General Public License | |
17 | ;;;; along with this software; see the file COPYING. If not, write to | |
18 | ;;;; the Free Software Foundation, Inc., 59 Temple Place, Suite 330, | |
19 | ;;;; Boston, MA 02111-1307 USA | |
20 | ||
21 | (use-modules (test-suite lib)) | |
22 | ||
23 | (define (display-line . args) | |
24 | (for-each display args) | |
25 | (newline)) | |
26 | ||
27 | (define (test-file) | |
28 | (tmpnam)) | |
29 | ||
30 | \f | |
31 | ;;;; Some general utilities for testing ports. | |
32 | ||
33 | ;;; Read from PORT until EOF, and return the result as a string. | |
34 | (define (read-all port) | |
35 | (let loop ((chars '())) | |
36 | (let ((char (read-char port))) | |
37 | (if (eof-object? char) | |
38 | (list->string (reverse! chars)) | |
39 | (loop (cons char chars)))))) | |
40 | ||
41 | (define (read-file filename) | |
42 | (let* ((port (open-input-file filename)) | |
43 | (string (read-all port))) | |
44 | (close-port port) | |
45 | string)) | |
46 | ||
47 | \f | |
48 | ;;;; Normal file ports. | |
49 | ||
50 | ;;; Write out an s-expression, and read it back. | |
0d572e91 JB |
51 | (catch-test-errors |
52 | (let ((string '("From fairest creatures we desire increase," | |
53 | "That thereby beauty's rose might never die,")) | |
54 | (filename (test-file))) | |
55 | (let ((port (open-output-file filename))) | |
56 | (write string port) | |
57 | (close-port port)) | |
58 | (let ((port (open-input-file filename))) | |
59 | (let ((in-string (read port))) | |
60 | (pass-if "file: write and read back list of strings" | |
61 | (equal? string in-string))) | |
62 | (close-port port)) | |
63 | (delete-file filename))) | |
000ee07f JB |
64 | |
65 | ;;; Write out a string, and read it back a character at a time. | |
0d572e91 JB |
66 | (catch-test-errors |
67 | (let ((string "This is a test string\nwith no newline at the end") | |
68 | (filename (test-file))) | |
69 | (let ((port (open-output-file filename))) | |
70 | (display string port) | |
71 | (close-port port)) | |
72 | (let ((in-string (read-file filename))) | |
73 | (pass-if "file: write and read back characters" | |
74 | (equal? string in-string))) | |
75 | (delete-file filename))) | |
000ee07f JB |
76 | |
77 | \f | |
78 | ;;;; Pipe ports. | |
79 | ||
80 | ;;; Run a command, and read its output. | |
0d572e91 JB |
81 | (catch-test-errors |
82 | (let* ((pipe (open-pipe "echo 'Howdy there, partner!'" "r")) | |
83 | (in-string (read-all pipe))) | |
84 | (close-port pipe) | |
85 | (pass-if "pipe: read" | |
86 | (equal? in-string "Howdy there, partner!\n")))) | |
000ee07f JB |
87 | |
88 | ;;; Run a command, send some output to it, and see if it worked. | |
0d572e91 JB |
89 | (catch-test-errors |
90 | (let* ((filename (test-file)) | |
91 | (pipe (open-pipe (string-append "grep Mommy > " filename) "w"))) | |
92 | (display "Now Jimmy lives on a mushroom cloud\n" pipe) | |
93 | (display "Mommy, why does everybody have a bomb?\n" pipe) | |
94 | (close-port pipe) | |
95 | (let ((in-string (read-file filename))) | |
96 | (pass-if "pipe: write" | |
97 | (equal? in-string "Mommy, why does everybody have a bomb?\n"))) | |
98 | (delete-file filename))) | |
000ee07f JB |
99 | |
100 | \f | |
101 | ;;;; Void ports. These are so trivial we don't test them. | |
102 | ||
103 | \f | |
104 | ;;;; String ports. | |
105 | ||
106 | ;;; Write text to a string port. | |
0d572e91 JB |
107 | (catch-test-errors |
108 | (let* ((string "Howdy there, partner!") | |
109 | (in-string (call-with-output-string | |
110 | (lambda (port) | |
111 | (display string port) | |
112 | (newline port))))) | |
113 | (pass-if "output string: display text" | |
114 | (equal? in-string (string-append string "\n"))))) | |
000ee07f JB |
115 | |
116 | ;;; Write an s-expression to a string port. | |
0d572e91 JB |
117 | (catch-test-errors |
118 | (let* ((sexpr '("more utterly random text" 1729 #(a vector) 3.1415926)) | |
119 | (in-sexpr | |
120 | (call-with-input-string (call-with-output-string | |
121 | (lambda (port) | |
122 | (write sexpr port))) | |
123 | read))) | |
124 | (pass-if "input and output string: write/read sexpr" | |
125 | (equal? in-sexpr sexpr)))) | |
000ee07f JB |
126 | |
127 | \f | |
128 | ;;;; Soft ports. No tests implemented yet. | |
129 | ||
130 | \f | |
131 | ;;;; Generic operations across all port types. | |
132 | ||
133 | (let ((port-loop-temp (test-file))) | |
134 | ||
135 | ;; Return a list of input ports that all return the same text. | |
136 | ;; We map tests over this list. | |
137 | (define (input-port-list text) | |
138 | ||
139 | ;; Create a text file some of the ports will use. | |
140 | (let ((out-port (open-output-file port-loop-temp))) | |
141 | (display text out-port) | |
142 | (close-port out-port)) | |
143 | ||
144 | (list (open-input-file port-loop-temp) | |
145 | (open-input-pipe (string-append "cat " port-loop-temp)) | |
146 | (call-with-input-string text (lambda (x) x)) | |
147 | ;; We don't test soft ports at the moment. | |
148 | )) | |
149 | ||
150 | (define port-list-names '("file" "pipe" "string")) | |
151 | ||
152 | ;; Test the line counter. | |
153 | (define (test-line-counter text second-line) | |
154 | (with-test-prefix "line counter" | |
155 | (let ((ports (input-port-list text))) | |
156 | (for-each | |
157 | (lambda (port port-name) | |
158 | (with-test-prefix port-name | |
159 | (pass-if "at beginning of input" | |
160 | (= (port-line port) 0)) | |
161 | (pass-if "read first character" | |
162 | (eqv? (read-char port) #\x)) | |
163 | (pass-if "after reading one character" | |
164 | (= (port-line port) 0)) | |
165 | (pass-if "read first newline" | |
166 | (eqv? (read-char port) #\newline)) | |
167 | (pass-if "after reading first newline char" | |
168 | (= (port-line port) 1)) | |
169 | (pass-if "second line read correctly" | |
170 | (equal? (read-line port) second-line)) | |
171 | (pass-if "read-line increments line number" | |
172 | (= (port-line port) 2)) | |
173 | (let loop () | |
174 | (if (not (eof-object? (read-line port))) | |
175 | (loop))) | |
176 | (pass-if "line count is 5 at EOF" | |
177 | (= (port-line port) 5)))) | |
178 | ports port-list-names) | |
179 | (for-each close-port ports) | |
180 | (delete-file port-loop-temp)))) | |
181 | ||
0d572e91 JB |
182 | (catch-test-errors |
183 | (with-test-prefix "newline" | |
184 | (test-line-counter | |
185 | (string-append "x\n" | |
186 | "He who receives an idea from me, receives instruction\n" | |
187 | "himself without lessening mine; as he who lights his\n" | |
188 | "taper at mine, receives light without darkening me.\n" | |
189 | " --- Thomas Jefferson\n") | |
190 | "He who receives an idea from me, receives instruction"))) | |
191 | ||
192 | (catch-test-errors | |
193 | (with-test-prefix "no newline" | |
194 | (test-line-counter | |
195 | (string-append "x\n" | |
196 | "He who receives an idea from me, receives instruction\n" | |
197 | "himself without lessening mine; as he who lights his\n" | |
198 | "taper at mine, receives light without darkening me.\n" | |
199 | " --- Thomas Jefferson\n" | |
200 | "no newline here") | |
201 | "He who receives an idea from me, receives instruction")))) |