bug#66046: [PATCH v4 2/3] tests: Add new compile-file tests.

Maxim Cournoyer <[email protected]>
Newsgroups gmane.lisp.guile.bugs
Message-ID <[email protected]>
Add a test for bug #66046.

To run just the compiler tests:

  ./meta/guile -L test-suite -L . test-suite/tests/compiler.test

* test-suite/tests/compiler.test (with-temporary-directory): New syntax.
(delete-file-recursively): New procedure.
("compile-file: relative include works")
("compile-file: relative include works with load path
canonicalization"): New tests.
---

(no changes since v1)

 test-suite/tests/compiler.test | 84 ++++++++++++++++++++++++++++++++--
 1 file changed, 81 insertions(+), 3 deletions(-)

diff --git a/test-suite/tests/compiler.test b/test-suite/tests/compiler.test
index 0b47d0e32..5cb7a8ef6 100644
--- a/test-suite/tests/compiler.test
+++ b/test-suite/tests/compiler.test
@@ -1,6 +1,6 @@
 ;;;; compiler.test --- tests for the compiler      -*- scheme -*-
-;;;; Copyright (C) 2008-2014, 2018, 2021-2022, 2024 Free Software Foundation, Inc.
-;;;; 
+;;;; Copyright (C) 2008-2014, 2018, 2021-2024 Free Software Foundation, Inc.
+;;;;
 ;;;; 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
@@ -18,15 +18,50 @@
 (define-module (tests compiler)
   #:use-module (test-suite lib)
   #:use-module (test-suite guile-test)
+  #:use-module (ice-9 ftw)
   #:use-module (system base compile)
   #:use-module ((language tree-il)
                 #:select (tree-il-src call-args))
   #:use-module ((system vm loader) #:select (load-thunk-from-memory))
-  #:use-module ((system vm program) #:select (program-sources source:addr)))
+  #:use-module ((system vm program) #:select (program-sources source:addr))
+  #:use-module (srfi srfi-26))
 
 (define read-and-compile
   (@@ (system base compile) read-and-compile))
 
+;;; Based on 'with-directory-excursion', from (guix build utils).
+(define-syntax-rule (with-temporary-directory body ...)
+  "Run BODY with DIR as the process's current directory."
+  (let ((init (getcwd))
+        (dir (mkdtemp "tempdir.XXXXXX")))
+   (dynamic-wind
+     (lambda ()
+       (chdir dir))
+     (lambda ()
+       body ...)
+     (lambda ()
+       (chdir init)
+       (delete-file-recursively dir)))))
+
+;;; XXX: Adapted from (guix build utils).
+(define* (delete-file-recursively dir)
+  "Delete DIR recursively, like `rm -rf', without following symlinks."
+  (file-system-fold (const #t)          ;enter
+                    (lambda (file stat result)   ; leaf
+                      (delete-file file))
+                    (const #t)                   ; down
+                    (lambda (dir stat result)    ; up
+                      (rmdir dir))
+                    (const #t)                   ; skip
+                    (lambda (file stat errno result)
+                      (format (current-error-port)
+                              "warning: failed to delete ~a: ~a~%"
+                              file (strerror errno)))
+                    #t
+                    dir
+
+                    ;; Don't follow symlinks.
+                    lstat))
 
 
 (with-test-prefix "basic"
@@ -441,3 +476,46 @@
         (set! proc ((load-thunk-from-memory bytecode)))
         (procedure? proc)))
     (pass-if-equal "proc executes" 42 (proc))))
+
+(with-test-prefix "compile-file"
+  ;; Setup test library sources in a temporary directory.
+  (let ((hello-sexp '(define-library (hello)
+                       (import (scheme base)
+                               (scheme write))
+                       (export hello)
+                       (include "hello/hello-impl.scm")))
+        (hello-impl-sexp '(begin
+                            (include "../external/nothing.scm")
+                            (include "body.scm")))
+        (hello-body-sexp '(define (hello)
+                            (display "hello!\n"))))
+    (with-temporary-directory
+     (mkdir "module")
+     (call-with-output-file "module/hello.scm"
+       (cut write hello-sexp <>))
+     (mkdir "module/hello")
+     (call-with-output-file "module/hello/hello-impl.scm"
+       (cut write hello-impl-sexp <>))
+     (call-with-output-file "module/hello/body.scm"
+       (cut write hello-body-sexp <>))
+     (mkdir "module/external")
+     (call-with-output-file "module/external/nothing.scm" (const #t))
+     (mkdir "build")
+     (chdir "build")
+
+     (pass-if "relative include works"
+       (compile-file "../module/hello.scm" #:output-file "hello.go")
+       #t)
+
+     ;; This used to fail, because compile-file's #:canonicalization
+     ;; defaults to 'relative, which causes 'scm_relativize_path' to
+     ;; strip the prefix not in the load path, to avoid baking an
+     ;; invalid source file reference in the byte compiled output file
+     ;; (see: https://bugs.gnu.org/66046).  This was fixed by having a
+     ;; '%file-port-stripped-prefixes' fluid to preserve the stripped
+     ;; prefix, to be used by 'include' to reconstruct the original
+     ;; complete relative file name.
+     (pass-if "relative include works with load path canonicalization"
+       (add-to-load-path (string-append (getcwd) "/../module"))
+       (compile-file "../module/hello.scm" #:output-file "hello.go")
+       #t))))
-- 
2.46.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.