defs-n-paths.lisp Unix DownloadWindows Download
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -*- Mode: Lisp -*- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; File		     - defs-n-paths.lisp
;; Description	     - Tester for student solutions
;; Author	     - Gail Anderson (ga at lostwithiel)
;; Created On	     - Tue Mar 14 19:19:08 2000
;; Last Modified On  -  Tue Jul 10 02:09:20 2001
;; Last Modified By  - Gail Anderson (ga at lostwithiel)
;; Update Count	     - 441
;; Status	     - Unknown
;; 
;; $Id: defs-n-paths.lisp,v 1.2 2003/01/23 09:04:20 colin Exp $
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(in-package :solution-tests)


;;; use htout

(eval-when (compile load eval)
  (use-package :htout))

;;; Contains all the definitions and load commands needed to set up
;;; the tester's environment for testing solutions to a particular
;;; exercise

;;; pathname defaults ; these are merged with the current value of
;;; *default-pathname-defaults*

(defparameter *submission-directory* '(:relative "submissions"))
(defparameter *submission-log-directory* '(:relative "submission-logs"))
(defparameter *submission-score-directory* '(:relative "submission-scores"))

(defparameter *total-sheet*
    (merge-pathnames
     (make-pathname
     :directory *submission-score-directory*
     :name "totals")))


;;; extensions to filenames

(defparameter *lisp-extn* ".lisp")
(defparameter *log-extn* ".html")
(defparameter *score-extn* ".html")


;;; Here, provide a list of pathnames of any test data, auxiliary test
;;; functions, or libraries needed to test the students' solutions;
;;; these should be pre-compiled

(defparameter *libs* nil)  ; etc.

(if *libs*
    (mapc #'load *libs*))


;;; Here, define *all-students* to be a list of the basenames of all
;;; the student solutions to be tested. These should live in the
;;; *submission-directory*

(defparameter *all-students* '("student"))

;;; global parameter which stores all the scorecards for all solutions
;;; tested

(defparameter *scores* (make-hash-table :test #'equalp))

;;; structure to score a student's final marks. This is defined as a
;;; separate structure (stored in a slot of the exercise structure) to
;;; provide an interface point for the test routines.

(defstruct student-scorecard 
  login-name
  author
  load-error
  loaded-comment
  compile-error
  compiled-comment
  other-comments
  symbol-scores)


;;; Macro for testing a particular call, and printing out the result.

;;; This has to be defined BEFORE the exercise-specific tests are loaded.


(defmacro test-call (num call expected comment &key (test #'equalp) print (stream t))
  `(progn
     (if *libs*
	 (mapc #'load *libs*))
     (let* ((args (rest ',call))
	    result
	    success)
       (multiple-value-bind (res err warn)
	   (block catch-warnings
	     (let ((warnings '()))
	       (handler-bind ((warning #'(lambda (w)
					   (push w warnings)))
			      (error #'(lambda (e)
					 (return-from catch-warnings
					   (values nil e warnings)))))
		 (let ((r ,call))
		   (values r nil warnings)))))
	 (cond ((eql ,expected ':ERROR)
		(if err (setf success t))
		(setf result err))
	       ((eql ,expected ':WARNING)
		(if warn (setf success t))
		(setf result warn))
	       (t
		(setf result res)
		(setf success (funcall ,test result ,expected)))))
       
       (if success
	   (with-html-output (,stream)
	     (:p
	      (format ,stream "Test ~D (~A): ~S successfully returned (or signalled) ~S with arguments: ~S"
		      ,num 
		      (format nil ,comment)
		      ',call
		      result
		      args)))
	   (with-html-output (,stream)
	     (:p
	      (format ,stream "********* FAULT ON TEST ~D (~A): ~S returned (or signalled): ~S instead of: ~S with arguments: ~S"
		      ,num
		      (format nil ,comment)
		      ',call
		      (if ,print (funcall ,print result) result)
		      (if ,print (funcall ,print ,expected) ,expected)
		      args)))))))