3

I'm trying to run tests in ASDF, which looks like this:

;;;; foo.asd

(defsystem "foo/tests"
  :depends-on ("foo"
               "fiveam")
  :components ((:module "tests"
                :components
                ((:file "main"))))
  :perform (test-op (op c) (symbol-call :fiveam '#:run! 'foo/tests:all-tests))

And my tests/main.lisp file starts off like this:

;;;; tests/main.lisp

(defpackage foo/tests
  (:use :cl
        :foo
        :fiveam)
  (:export :#run! :#all-tests))
(in-package :foo/tests)

When I run (asdf:test-system 'foo) in my REPL, I get dropped into the debugger with a LOAD-SYSTEM-DEFINITION-ERROR. The debugger is complaining that The symbol "ALL-TESTS" is not external in the FOO/TESTS package.

However, I am clearly exporting the symbol in the foo/tests package. Can somebody please tell me what I'm missing here and why the Lisp compiler isn't seeing the external symbol? Thank you very much.

Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
jay
  • 1,524
  • 4
  • 25
  • 45
  • 2
    `foo.asd` is being read before `main.lisp` is loaded, so the `defpackage` hasn't been executed yet. – Barmar Jan 30 '20 at 01:58
  • @Barmar: that's what the `symbol-call` form solves. – Svante Jan 30 '20 at 08:33
  • 1
    @svante: `foo/tests:all-tests` is an external symbol in a not yet defined (?) package. How can that be solved by `symbol-call`, which is not executed at read-time? Somehow he needs to have that package already available, before the DEFSYSTEM form can be read? – Rainer Joswig Jan 30 '20 at 10:11
  • 1
    @RainerJoswig: Sorry, you're both right, I had only glanced over the form. As written, it only solves the problem for `fiveam:run!`, not for the argument. – Svante Jan 30 '20 at 12:11
  • It's long been said that the choice to describe packages in Chapter 11 of CLTL was deliberate. – Barmar Jan 30 '20 at 16:29

1 Answers1

4

The syntax for an uninterned symbol is #:foo, not :#foo.

You also need to resolve the symbols in the :perform form at run-time, e. g. through uiop:find-symbol*, just like you use uiop:symbol-call there.

:perform (test-op (op c)
           (symbol-call :fiveam '#:run!
                        (find-symbol* '#:all-tests '#:foo/tests)))

Or, since you seem to export a run! function from your test package, you might want to call that instead of fiveam:run!:

:perform (test-op (op c)
           (symbol-call '#:foo/tests '#:run!))
Svante
  • 50,694
  • 11
  • 78
  • 122