· Cambiar idioma (Actualmente: Español)

SRFI 64: Pensando en agregar más formas para pruebas

Agosto 05, 2021 13:03 -0500

Al parecer, porque no he probado todavía, uno podría agregar formas nuevas para casos de prueba propios escribiendo macros nuevos. Por ejemplo, esta es la definición de la forma básica test-assert que hace parte de SRFI 64.

(define-syntax test-assert
  (lambda (x)
    (syntax-case (list x (list (syntax quote) (%test-source-line2 x))) ()
      (((mac tname expr) line)
       (syntax
	(let* ((r (test-runner-get))
	       (name tname))
	  (test-result-alist! r (cons (cons 'test-name tname) line))
	  (%test-comp1body r expr))))
      (((mac expr) line)
       (syntax
	(let* ((r (test-runner-get)))
	  (test-result-alist! r line)
	  (%test-comp1body r expr)))))))
      
Código 1. Definición del macro test-assert en el módulo (srfi srfi-64) de GNU Guile.

Entonces, test-assert es un macro. Según el manual de Guile, un macro es un programa que se ejecuta en otros programas, traduciendo un EDSL (Embedded Domain Specific Language) a Scheme básico. Un macro es una asociación entre una palabra clave sintáctica (syntax keyword) y un transformador sintáctico (syntax transformer). Un transformador sintáctico es un procedimiento que traduce de una sintaxis a otra sintaxis.

Teniendo en cuenta lo anterior, interpretaría la definición del Código 1 así:

(define-syntax test-assert  ; ← Palabra clave sintáctica.
  ;; Procedimiento anónimo que representa el transformador sintáctico.
  (lambda (x)
    (syntax-case (list x (list (syntax quote) (%test-source-line2 x))) ()
      ;; Sintaxis a la que se traducen los casos «test-assert» de forma:
      ;; (test-assert NOMBRE_DE_LA_PRUEBA EXPRESIÓN)
      ;;      ↑                ↑              ↑
      ;;     mac             tname           expr
      (((mac tname expr) line)
       (syntax
	(let* ((r (test-runner-get))
	       (name tname))  ; ¿Para qué «name» si no se usa?
          ;; Actualización de resultados en el ejecutor de pruebas.
	  (test-result-alist! r (cons (cons 'test-name tname) line))
	  (%test-comp1body r expr))))
      ;; Sintaxis a la que se traducen los casos «test-assert» que no
      ;; especifican el nombre de la prueba; o sea, los de forma:
      ;; (test-assert EXPRESIÓN)
      ;;      ↑           ↑
      ;;     mac         expr
      (((mac expr) line)
       (syntax
	(let* ((r (test-runner-get)))
          ;; Actualización de resultados en el ejecutor de pruebas.
	  (test-result-alist! r line)
	  (%test-comp1body r expr)))))))
      
Código 2. Mi interpretación actual del macro test-assert del Código 1.

Si todo encaja bien, la primera forma que pienso escribir es la forma test-false, que ya he necesitado muchas veces, pero que he tenido que suplir con test-assert, que es menos legible para el caso. También quiero formas específicas para cosas web, para lo cual tal vez necesite equivalentes a las Assertions de Django.

Pero hay algo que me dejó pensando... Leyendo la definición de las formas para casos de prueba de SRFI 64 uno ve que los transformadores sintácticos no son procedimientos puros porque modifican el estado del ejecutor de pruebas disponible durante la ejecución; esto es de esperarse porque SRFI 64 no es funcional, pero, ¿no existirá una infraestructura de pruebas funcional o tan funcional como sea posible?

Temas relacionados: