Shinmera / parachute

An extensible and cross-compatible testing framework.
https://shinmera.github.io/parachute
zlib License
94 stars 9 forks source link

*package* is not set to the test's home package #6

Closed fstamour closed 5 years ago

fstamour commented 5 years ago

Long story short, I was trying to test a function used by a macro that would create a symbol in the calling package and it was working from the repl, but not when called by the tests.

Here's what I did to reproduce the problem and a fix that I found (probably not the best). If it's too messy, I'll come back to it and try to break it down a little, right now I need to go.

Thank you!

(in-package cl-user)

(defpackage a (:use cl) (:export a))

(in-package a)

(defun a (x)
  (print *package*)
  (list (intern (symbol-name x) *package*)))

#+nil
(defun a (x)
  (list (alexandria:symbolicate x)))

(defpackage b (:use cl) (:export b))

(defpackage c (:use cl))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(in-package c)

(a:a 'b:b)
;; => '(b)

(defun get-package-name (list)
  (mapcar #'(lambda (element)
              (package-name (symbol-package element)))
          list))

(get-package-name
 (a:a 'b:b))
;; => C

(parachute:define-test test
  (parachute:is equalp (a:a 'b:b) '(c::b)))

(parachute:define-test test2
  (parachute:is equalp
                (get-package-name (a:a 'b:b))
                '("C")))

(parachute:test 'c)

#|
? C::TEST2
0.000 ✔   (is equalp (get-package-name (a 'b)) '("C"))
0.000 ✔ C::TEST2
? C::TEST
0.000 ✔   (is equalp (a 'b) '(b))
0.000 ✔ C::TEST

;; Summary:
Passed:     2
Failed:     0
Skipped:    0
|#

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defpackage d (:use cl))

(in-package d)

(parachute:test 'c)

#|
;; Summary:
Passed:     0
Failed:     2
Skipped:    0

;; Failures:
1/   1 tests failed in C::TEST2
The test form   '("C")
evaluated to    ("C")
when            ("D")
was expected to be equal under EQUALP.

1/   1 tests failed in C::TEST
The test form   '(b)
evaluated to    (b)
when            (b)
was expected to be equal under EQUALP.
|#

#|
The tests where defined in C, but ran from D.
Somehow the package D leaked into the test execution.
|#

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun parachute:test (designator &rest args &key (report 'plain) &allow-other-keys)
  (let* ((tests (resolve-tests designator))
         (report (apply #'make-instance report
                        :expression designator
                        (removef args :report)))
         (*context* report))
    (dolist (test tests)
      (let ((*package* (home test))) ;; <===== Added this
        (eval-in-context report (result-for-testable test report))))
    (summarize report)))

(parachute:test 'c)
;;; And now it passes
Shinmera commented 5 years ago

Let me know if this doesn't fix it.

fstamour commented 4 years ago

It did fix it :)