;;; Weeb --- Web microframework for GNU Guile ;;; Copyright © 2026 Jakob Kreuze ;;; ;;; This file is part of Weeb. ;;; ;;; Weeb is free software: you can redistribute it and/or modify it ;;; under the terms of the GNU Affero General Public License as ;;; published by the Free Software Foundation, either version 3 of the ;;; License, or (at your option) any later version. ;;; ;;; Weeb is distributed in the hope that it will be useful, but WITHOUT ;;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ;;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General ;;; Public License for more details. ;;; ;;; You should have received a copy of the GNU Affero General Public ;;; License along with Weeb. If not, see . (use-modules (srfi srfi-11) (srfi srfi-64) (weeb request) (weeb response) (weeb router) (weeb struct)) ;; Private imports for testing purposes. (define uri-template->regexp-string (@@ (weeb router) uri-template->regexp-string)) (define handle-route (@@ (weeb router) handle-route)) (test-runner-current (test-runner-simple)) (test-begin "weeb-router") (test-group "simple static route" (let-values (((re vars) (uri-template->regexp-string "/health"))) (test-equal "^/health$" re) (test-equal '() vars))) (test-group "single variable route" (let-values (((re vars) (uri-template->regexp-string "/user/:id:"))) (test-equal "^/user/([^/]+)$" re) (test-equal '(id) vars))) (test-group "multiple variables with trailing slash" (let-values (((re vars) (uri-template->regexp-string "/org/:org_id:/user/:user_id:/"))) (test-equal "^/org/([^/]+)/user/([^/]+)/?$" re) (test-equal '(org_id user_id) vars))) (test-group "middle variables" (let-values (((re vars) (uri-template->regexp-string "/api/:version:/data"))) (test-equal "^/api/([^/]+)/data$" re) (test-equal '(version) vars))) (test-group "handle route" (define (handler r id) (list id)) (define-router router ("/user/:id:" (GET) handler)) (let* ((req (make-struct 'GET "/user/123" #f #f #f)) (route-obj (car router))) (test-equal '("123") (handle-route req route-obj))) (let ((req (make-struct 'POST "/user/123" #f #f #f)) (route-obj (car router))) (test-eqv #f (handle-route req route-obj)))) (test-group "iter-routes 1" (define (static-handler r) "static") (define (api-handler r version) (list version)) (define-router router ("/static/" (GET) static-handler) ("/api/:version:/data" (GET) api-handler)) (let ((req (make-struct 'GET "/api/v1/data" #f #f #f))) (test-equal '("v1") (iter-routes req router)))) (test-group "iter-routes 2" (define (handler r org_id user_id) (list org_id user_id)) (define-router router ("/org/:org_id:/user/:user_id:/" (GET) handler)) (let ((req (make-struct 'GET "/org/42/user/99/" #f #f #f))) (test-equal '("42" "99") (iter-routes req router)))) (test-group "edge cases 1" (define (handler request) "ok") (define-router router ("/health" (GET) handler)) (let ((req (make-struct 'GET "/health" #f #f #f))) (test-equal "ok" (iter-routes req router)))) (test-group "edge cases 2" (define (handler request) "home") (define-router router ("/" (GET) handler)) (let ((req (make-struct 'GET "/" #f #f #f))) (test-equal "home" (iter-routes req router)))) (test-group "edge cases 3: anchor validation" (define-router router ("/health" (GET) (lambda (r) "ok")) ("/user/:id:" (GET) (lambda (r id) id)) ("/" (GET) (lambda (r) "home"))) (let* ((req (make-struct 'GET "/health/extra" #f #f #f)) (res (any->response (iter-routes req router)))) (with-accessors (res code) (test-eqv 404 code))) (let* ((req (make-struct 'GET "/user/123/extra" #f #f #f)) (res (any->response (iter-routes req router)))) (with-accessors (res code) (test-eqv 404 code))) (let* ((req (make-struct 'GET "/anything" #f #f #f)) (res (any->response (iter-routes req router)))) (with-accessors (res code) (test-eqv 404 code)))) (test-end)