projects/guix·blob master · refs

443 lines · 9.9 KiB

1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2021-2023, 2025 Ludovic Courtès <[email protected]>
3;;;
4;;; This file is part of GNU Guix.
5;;;
6;;; GNU Guix is free software; you can redistribute it and/or modify it
7;;; under the terms of the GNU General Public License as published by
8;;; the Free Software Foundation; either version 3 of the License, or (at
9;;; your option) any later version.
10;;;
11;;; GNU Guix is distributed in the hope that it will be useful, but
12;;; 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 GNU Guix. If not, see <http://www.gnu.org/licenses/>.
18
19(define-module (tests-style)
20 #:use-module (guix read-print)
21 #:use-module (guix gexp) ;for the reader extensions
22 #:use-module (srfi srfi-34)
23 #:use-module (srfi srfi-35)
24 #:use-module (srfi srfi-64)
25 #:use-module (ice-9 match))
26
27(define-syntax-rule (test-pretty-print str args ...)
28 "Test equality after a round-trip where STR is passed to
29'read-with-comments' and the resulting sexp is then passed to
30'pretty-print-with-comments'."
31 (test-equal str
32 (call-with-output-string
33 (lambda (port)
34 (let ((exp (call-with-input-string str
35 read-with-comments)))
36 (pretty-print-with-comments port exp args ...))))))
37
38(define-syntax-rule (test-pretty-print/sequence str args ...)
39 "Likewise, but read and print entire sequences rather than individual
40expressions."
41 (test-equal str
42 (call-with-output-string
43 (lambda (port)
44 (let ((lst (call-with-input-string str
45 read-with-comments/sequence)))
46 (pretty-print-with-comments/splice port lst args ...))))))
47
48
49(test-begin "read-print")
50
51(test-assert "read-with-comments: missing closing paren"
52 (guard (c ((error? c) #t))
53 (call-with-input-string "(what is going on?"
54 read-with-comments)))
55
56(test-equal "read-with-comments: dot notation"
57 (cons 'a 'b)
58 (call-with-input-string "(a . b)"
59 read-with-comments))
60
61(test-equal "read-with-comments: half dot notation"
62 '(lambda x x)
63 (call-with-input-string "(lambda (. x) x)"
64 read-with-comments))
65
66(test-equal "read-with-comments: list with blank line"
67 `(list with ,(vertical-space 1) blank line)
68 (call-with-input-string "\
69(list with
70
71 blank line)\n"
72 read-with-comments))
73
74(test-equal "read-with-comments: list with multiple blank lines"
75 `(list with ,(comment ";multiple\n" #t)
76 ,(vertical-space 3) blank lines)
77 (call-with-input-string "\
78(list with ;multiple
79
80
81
82 blank lines)\n"
83 read-with-comments))
84
85(test-equal "read-with-comments: top-level blank lines"
86 (list (vertical-space 2) '(a b c) (vertical-space 2))
87 (call-with-input-string "
88
89(a b c)\n\n"
90 (lambda (port)
91 (list (read-with-comments port)
92 (read-with-comments port)
93 (read-with-comments port)))))
94
95(test-equal "read-with-comments: top-level page break"
96 (list (comment ";; Begin.\n") (vertical-space 1)
97 (page-break)
98 (comment ";; End.\n"))
99 (call-with-input-string "\
100;; Begin.
101
102
103;; End.\n"
104 (lambda (port)
105 (list (read-with-comments port)
106 (read-with-comments port)
107 (read-with-comments port)
108 (read-with-comments port)))))
109
110(test-pretty-print "(list 1 2 3 4)")
111(test-pretty-print "((a . 1) (b . 2))")
112(test-pretty-print "(a b c . boom)")
113(test-pretty-print "(list 1
114 2
115 3
116 4)"
117 #:long-list 3
118 #:indent 20)
119(test-pretty-print "\
120(list abc
121 def)"
122 #:max-width 11)
123(test-pretty-print "\
124(#:foo
125 #:bar)"
126 #:max-width 10)
127
128(test-pretty-print "\
129(#:first 1
130 #:second 2
131 #:third 3)")
132
133(test-pretty-print "\
134((x
135 1)
136 (y
137 2)
138 (z
139 3))"
140 #:max-width 3)
141
142(test-pretty-print "\
143(let ((x 1)
144 (y 2)
145 (z 3)
146 (p 4))
147 (+ x y))"
148 #:max-width 11)
149
150(test-pretty-print "\
151(begin
152 1+ 1- 123/ 456*
153 (1+ 41))")
154
155(test-pretty-print "\
156(lambda (x y)
157 ;; This is a procedure.
158 (let ((z (+ x y)))
159 (* z z)))")
160
161(test-pretty-print "\
162(case x
163 ((1)
164 'one)
165 ((2)
166 'two))")
167
168(test-pretty-print "\
169(cond
170 ((zero? x)
171 'zero)
172 ((odd? x)
173 'odd)
174 (else #f))")
175
176(test-pretty-print "\
177(parameterize ((a 1)
178 (b 2))
179 (call f g h))")
180
181(test-pretty-print "\
182#~(string-append #$coreutils \"/bin/uname\")")
183
184(test-pretty-print "\
185(package
186 (inherit coreutils)
187 (version \"42\"))")
188
189(test-pretty-print "\
190(modify-phases %standard-phases
191 (add-after 'unpack 'post-unpack
192 (lambda _
193 #t))
194 (add-before 'check 'pre-check
195 (lambda* (#:key inputs #:allow-other-keys)
196 do things ...)))")
197
198(test-pretty-print "\
199(#:phases (modify-phases sdfsdf
200 (add-before 'x 'y
201 (lambda _
202 xyz))))")
203
204(test-pretty-print "\
205(string-append \"a\\tb\" \"\\n\")")
206
207(test-pretty-print "\
208(display \"This is a very long string.
209It contains line breaks, which are preserved,
210because it's a long string.\")")
211
212(test-pretty-print "\
213(description \"abcdefghijkl
214mnopqrstuvwxyz.\")"
215 #:max-width 30)
216
217(test-pretty-print "\
218(description
219 \"abcdefghijkl
220mnopqrstuvwxyz.\")"
221 #:max-width 12)
222
223(test-pretty-print "\
224(description
225 \"abcdefghijklmnopqrstuvwxyz\")"
226 #:max-width 33)
227
228(test-pretty-print "\
229(list ;margin comment
230 a b c)")
231
232(test-pretty-print "\
233(list
234 ;; This is a line comment immediately following the list head.
235 #:test-flags #~(list \"-m\" \"not external and not samples\"))")
236
237(test-pretty-print "\
238(modify-phases %standard-phases
239 (replace 'build
240 ;; Nicely indented in 'modify-phases' context.
241 (lambda _
242 #t)))")
243
244(test-pretty-print "\
245(modify-inputs inputs
246 ;; Regular indentation for 'replace' here.
247 (replace \"gmp\" gmp))")
248
249(test-pretty-print "\
250#~(modify-phases phases
251 (add-after 'whatever 'something-else
252 (lambda _
253 ;; This comment appears inside a gexp.
254 42)))")
255
256(test-pretty-print "\
257#~(list #$@(list coreutils ;yup
258 grep) ;margin comment
259 #+sed
260
261 ;; Line comment.
262 #$grep)")
263
264(test-pretty-print "\
265(package
266 ;; Here 'source', 'sha256', and 'arguments' must be
267 ;; immediately followed by a newline.
268 (source
269 (origin
270 (method url-fetch)
271 (sha256
272 (base32 \"not a real base32 string\"))))
273 (arguments
274 '(#:phases %standard-phases
275 #:tests? #f)))")
276
277;; '#:key value' is kept on the same line, except when followed by a gexp.
278(test-pretty-print "\
279(package
280 (name \"keyword-value-same-line\")
281 (arguments
282 (list
283 #:phases
284 #~(modify-phases %standard-phases
285 (add-before 'x 'y
286 (lambda* (#:key inputs #:allow-other-keys)
287 (foo bar baz))))
288 #:make-flags
289 #~'(\"ANSWER=42\")
290 #:tests? #f)))")
291
292(test-pretty-print "\
293(let ((x 1)
294 (y 2)
295 (z (let* ((a 3)
296 (b 4))
297 (+ a b))))
298 (list x y z))")
299
300(test-pretty-print "\
301(begin
302 (chmod \"foo\" #o750)
303 (chmod port
304 (logand #o644
305 (lognot (umask))))
306 (logand #x7f xyz))")
307
308(test-pretty-print "\
309(substitute-keyword-arguments (package-arguments x)
310 ((#:phases phases)
311 `(modify-phases ,phases
312 (add-before 'build 'do-things
313 (lambda _
314 #t))))
315 ((#:configure-flags flags)
316 `(cons \"--without-any-problem\"
317 ,flags)))")
318
319(test-pretty-print "\
320(vertical-space one:
321
322 two:
323
324
325 three:
326
327
328
329 end)")
330
331(test-pretty-print "\
332(vertical-space one
333
334 ;; Comment after blank line.
335 two)")
336
337(test-pretty-print "\
338(begin
339 break
340
341 ;; page break above
342 end)")
343
344(test-pretty-print "\
345(home-environment
346 (services
347 (list (service-type home-bash-service-type))))")
348
349(test-pretty-print/sequence "\
350;;; This is a top-level comment.
351
352
353;; Above is a page break.
354(this is an sexp
355 ;; with a comment
356 !!)
357
358;; The end.\n")
359
360(test-pretty-print/sequence "
361;;; Hello!
362;;; Notice that there are three semicolons here.
363
364(define-module (foo bar)
365 #:use-module (guix)
366 #:use-module (gnu))
367
368
369;; And now, the OS.
370(operating-system
371 (host-name \"komputilo\")
372 (locale \"eo_EO.UTF-8\")
373
374 (services
375 (cons (service mcron-service-type) %base-services)))\n"
376 #:format-comment canonicalize-comment)
377
378(test-equal "pretty-print-with-comments, canonicalize-comment"
379 "\
380(list abc
381 ;; Not a margin comment.
382 ;; Ditto.
383 ;;
384 ;; There's a blank line above.
385 def ;margin comment
386 ghi)"
387 (let ((sexp (call-with-input-string
388 "\
389(list abc
390 ;Not a margin comment.
391 ;;; Ditto.
392 ;;;;;
393 ; There's a blank line above.
394 def ;; margin comment
395 ghi)"
396 read-with-comments)))
397 (call-with-output-string
398 (lambda (port)
399 (pretty-print-with-comments port sexp
400 #:format-comment
401 canonicalize-comment)))))
402
403(test-equal "pretty-print-with-comments, canonicalize-vertical-space"
404 "\
405(list abc
406
407 def
408
409 ;; last one
410 ghi)"
411 (let ((sexp (call-with-input-string
412 "\
413(list abc
414
415
416
417 def
418
419
420;; last one
421 ghi)"
422 read-with-comments)))
423 (call-with-output-string
424 (lambda (port)
425 (pretty-print-with-comments port sexp
426 #:format-vertical-space
427 canonicalize-vertical-space)))))
428
429(test-equal "pretty-print-with-comments, multi-line comment"
430 "\
431(list abc
432 ;; This comment spans
433 ;; two lines.
434 def)"
435 (call-with-output-string
436 (lambda (port)
437 (pretty-print-with-comments port
438 `(list abc ,(comment "\
439;; This comment spans\n
440;; two lines.\n")
441 def)))))
442
443(test-end)