2014-04-07 7 views
8

Trovo che lo sviluppo incrementale tende a interrompersi quando si codifica per Hunchentoot.Accesso agli oggetti richiesta Hunchentoot dal REPL per il debug

Ad esempio, potrei scrivere una pagina Web composta da alcune funzioni. Se una di queste funzioni interne contiene una chiamata a - say - hunchentoot: post-parametri *, non riesco a testare facilmente la funzione nel REPL. Sconterà perché * richiesta * non esiste a meno che la pagina non venga chiamata da un client web.

Sarebbe bello se qualche funzione-o altro-source esisteva tale che ho potuto testare la mia funzione così:

>(let* ((*request* (get-previous-request-from-somewhere)) 
     (*session* (slot-value *request* 'hunchentoot:session))) 
    (my-function <whatever params>)) 

lo fa o qualcosa di simile esistere? Sto trascurando un approccio migliore al debugging?

+0

Sembra che tu abbia solo bisogno di creare un'apparecchiatura per restituire una richiesta fittizia. Questo non dovrebbe essere molto difficile. Per esempio vedi: https://github.com/russell/planet-git/blob/master/t/traverser.lisp#L55-L63 fiveam ha fixture se sei così inclinato – PuercoPop

risposta

6

La mia soluzione provvisoria simile a questa:

(defparameter *save-last-request* t) 
(defvar *last-request* nil) 

(defun store-request() 
    (when *save-last-request* 
    (setf *last-request* *request*))) 

(defmacro with-last-request (&body body) 
    `(let* ((*request* *last-request*) 
     (*session* (slot-value *request* 'hunchentoot:session))) 
    ,@body)) 

Funziona benissimo con l'avvertenza che ogni gestore ha bisogno di fare una chiamata a store-request.

+0

Dato che questo è almeno mezzo kludge (poiché la richiesta del negozio deve essere chiamata esplicitamente), ho dei dubbi da concedere all'intera taglia - se qualcuno fosse così gentile da dare un altro +1, metà della taglia sarebbe concessa automaticamente - quindi per favore vota:) –

1

Penso che la cosa più semplice da fare potrebbe essere quella di utilizzare una classe di richiesta personalizzata che introduce un modo per persistere le richieste da qualche parte nella catena di inizializzazione.

Ecco un semplice esempio di un approccio. Una sottoclasse di richieste personalizzata che salva il suo stato, in uno stack globale.

È possibile impostare le accettatori di utilizzare Request-classi personalizzate utilizzando

(setf (acceptor-request-class acceptor) new-value)

quindi qualcosa di simile

(defparameter *requests* nil) 
(defclass my-request (hunchentoot:request)()) 
(defmethod initialize-instance :after ((req my-request) &key) 
    (push req *requests*)) 

e quindi impostare la classe richiesta di accettazione per utilizzare questo quando fate la vostra accettatore es

(setf (hunchentoot:acceptor-request-class 
     (make-instance 'hunchentoot:easy-acceptor)) 'my-request) 

Ogni volta che una richiesta è stato creato da questo accettatore di passare al gestore, verrà aggiunto alla lista *requests*.

se si utilizza una variabile per specificare il nome della classe di richiesta, è possibile attivare e disattivare questa classe per lo sviluppo/debug.

È quindi possibile ricevere richieste da questa pila nel bind di test.

Problemi correlati