;;; Excercise the `resolve' routines. -*- Scheme -*- ;;; ;;; Copyright (C) 2009, 2021 Ludovic Courtès ;;; ;;; This file is part of Skribilo. ;;; ;;; Skribilo is free software; you can redistribute it and/or modify it ;;; under the terms of the GNU Lesser General Public License as published by ;;; the Free Software Foundation; either version 3 of the License, or (at ;;; your option) any later version. ;;; ;;; Skribilo 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 Lesser ;;; General Public License for more details. ;;; ;;; You should have received a copy of the GNU Lesser General Public License ;;; along with this program. If not, see . (define-module (tests resolve) #:use-module (skribilo ast) #:use-module (skribilo engine) #:use-module (skribilo resolve) #:use-module (skribilo package base) #:use-module (srfi srfi-64)) (define %engine (find-engine 'base)) (test-begin "resolve") (test-assert "parents" (let* ((doc (document #:title "Doc" (chapter #:title "C" (section #:title "S" (p "par"))))) (ch (car (markup-body doc))) (sec (car (markup-body ch))) (par (car (markup-body sec)))) (and (is-markup? ch 'chapter) (eq? (ast-parent ch) 'unspecified) (begin (resolve! doc %engine '()) (and (eq? (ast-parent ch) doc) (eq? (ast-parent sec) ch) (eq? (ast-parent par) sec)))))) (test-assert "root document has no parent" (let ((doc (document #:title "Doc"))) (resolve! doc %engine '()) (and (not (ast-parent doc)) (eq? doc (ast-document doc))))) (test-assert "nested document has a parent" ;; Nested documents are sometimes used in the manual. (let* ((doc (document #:title "Doc" (document #:title "Nested Doc" (chapter #:title "C")))) (sub (car (markup-body doc))) (ch (car (markup-body sub)))) (resolve! doc %engine '()) (and (not (ast-parent doc)) (document? sub) (eq? doc (ast-document doc)) (eq? doc (ast-parent sub))))) (test-assert "nested document is its own `ast-document'" (let* ((doc (document #:title "Doc" (document #:title "Nested Doc" (chapter #:title "C")))) (sub (car (markup-body doc))) (ch (car (markup-body sub)))) (resolve! doc %engine '()) (and (document? sub) (eq? sub (ast-document sub)) (eq? sub (ast-document ch))))) (test-assert "unresolved node in body" (let* ((resolved? #f) (doc (document #:title "Doc" (resolve (lambda (n e env) (set! resolved? #t)))))) (and (not resolved?) (begin (resolve! doc %engine '()) resolved?)))) (test-assert "unresolved node in unresolved node in body" (let* ((resolved? #f) (doc (document #:title "Doc" (resolve (lambda (n e env) (resolve (lambda (n e env) (set! resolved? #t)))))))) (and (not resolved?) (begin (resolve! doc %engine '()) resolved?)))) (test-assert "unresolved node in options" (let* ((resolved? #f) (doc (document #:title (resolve (lambda (n e env) (set! resolved? #t))) "body..."))) (and (not resolved?) (begin (resolve! doc %engine '()) resolved?)))) (test-assert "unresolved node in processor body" (let* ((resolved? #f) (doc (document #:title "Doc" (processor #:combinator (lambda (e1 e2) e1) (resolve (lambda (n e env) (set! resolved? #t))))))) (and (not resolved?) (begin (resolve! doc %engine '()) resolved?)))) (test-assert "unresolved node in nested document" (let* ((resolved? #f) (doc (document #:title "Outer" (document #:title "Inner" (resolve (lambda (n e env) (set! resolved? #t))))))) (and (not resolved?) (begin (resolve! doc %engine '()) resolved?)))) (test-assert "unresolved node product has a parent" (let* ((doc (document #:title "Doc" (resolve (lambda (n e env) (chapter #:title "C")))))) (resolve! doc %engine '()) (let ((ch (car (markup-body doc)))) (and (is-markup? ch 'chapter) (eq? (ast-parent ch) doc))))) (test-assert "node bindings" (let* ((doc (document #:title "Doc" (chapter #:title "C" #:ident "c" (section #:title "S" #:ident "s")))) (ch (car (markup-body doc))) (sec (car (markup-body ch)))) (and (not (document-lookup-node doc "c")) (not (document-lookup-node doc "s")) (begin (resolve! doc %engine '()) (and (eq? (document-lookup-node doc "c") ch) (eq? (document-lookup-node doc "s") sec)))))) (test-assert "unresolved node bindings" ;; Make sure nodes returned by `unresolved' nodes are eventually bound. (let* ((doc (document #:title "Doc" (resolve (lambda (n e env) (chapter #:title "C" #:ident "c" (section #:title "S" #:ident "s"))))))) (and (not (document-lookup-node doc "c")) (not (document-lookup-node doc "s")) (begin (resolve! doc %engine '()) (and (is-markup? (document-lookup-node doc "c") 'chapter) (is-markup? (document-lookup-node doc "s") 'section)))))) (test-assert "nested document bindings" ;; Bindings in nested documents are scoped. This was not the case prior ;; to 0.9.2. (let* ((doc (document #:title "Doc" (chapter #:ident "outer") (document #:title "Nested Doc" (chapter #:ident "inner")))) (out (car (markup-body doc))) (sub (cadr (markup-body doc))) (in (car (markup-body sub)))) (resolve! doc %engine '()) (and (let ((x (document-lookup-node doc "outer"))) (and (is-markup? x 'chapter) (eq? (ast-document x) doc))) (not (document-lookup-node doc "inner")) (let ((x (document-lookup-node sub "inner"))) (and (is-markup? x 'chapter) (eq? (ast-document x) sub)))))) (test-assert "resolved nested document bindings" ;; Prior to 0.9.2, nodes of a sub-document returned by an `unresolved' node ;; would be bound in the root document. (let* ((doc (document #:title "Doc" (resolve (lambda (n e env) (document #:title "Nested Doc" (chapter #:ident "inner"))))))) (resolve! doc %engine '()) (and (not (document-lookup-node doc "inner")) (let* ((sub (car (markup-body doc))) (ch (car (markup-body sub))) (x (document-lookup-node sub "inner"))) (and (document? sub) (is-markup? x 'chapter) (eq? x ch) (eq? (ast-parent x) sub) (eq? (ast-document x) sub)))))) (test-assert "node bindings in processor body" (let* ((doc (document #:title "Doc" (processor #:combinator (lambda (e1 e2) e1) (chapter #:ident "c"))))) (resolve! doc %engine '()) (let* ((proc (car (markup-body doc))) (ch (car (markup-body proc))) (ch* (document-lookup-node doc "c"))) (eq? ch ch*)))) (test-end "resolve")