texinfo.test 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. ;;;; texinfo.test -*- scheme -*-
  2. ;;;;
  3. ;;;; Copyright (C) 2010, 2011, 2012, 2013, 2014, 2020 Free Software Foundation, Inc.
  4. ;;;; Copyright (C) 2001,2002 Oleg Kiselyov <oleg at pobox dot com>
  5. ;;;;
  6. ;;;; This library is free software; you can redistribute it and/or
  7. ;;;; modify it under the terms of the GNU Lesser General Public
  8. ;;;; License as published by the Free Software Foundation; either
  9. ;;;; version 3 of the License, or (at your option) any later version.
  10. ;;;;
  11. ;;;; This library is distributed in the hope that it will be useful,
  12. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. ;;;; Lesser General Public License for more details.
  15. ;;;;
  16. ;;;; You should have received a copy of the GNU Lesser General Public
  17. ;;;; License along with this library; if not, write to the Free Software
  18. ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. ;;; Commentary:
  20. ;;
  21. ;; Unit tests for (sxml texinfo). Adapted from xml.ssax.scm.
  22. ;;
  23. ;;; Code:
  24. (define-module (test-suite texinfo)
  25. #:use-module (test-suite lib)
  26. #:use-module (texinfo))
  27. (define exception:eof-while-reading-token
  28. '(parser-error . "^EOF while reading a token"))
  29. (define exception:wrong-character
  30. '(parser-error . "^Wrong character"))
  31. (define exception:eof-while-reading-char-data
  32. '(parser-error . "^EOF while reading char data"))
  33. (define exception:no-settitle
  34. '(parser-error . "^No \\\\n@settitle found"))
  35. (define exception:unexpected-arg
  36. '(parser-error . "^@-command didn't expect more arguments"))
  37. (define exception:bad-enumerate
  38. '(parser-error . "^Invalid"))
  39. (define nl (string #\newline))
  40. (define texinfo:read-verbatim-body
  41. (@@ (texinfo) read-verbatim-body))
  42. (with-test-prefix "test-read-verbatim-body"
  43. (define (read-verbatim-body-from-string str)
  44. (define (consumer fragment foll-fragment seed)
  45. (cons* (if (equal? foll-fragment (string #\newline))
  46. (string-append " NL" nl)
  47. foll-fragment)
  48. fragment seed))
  49. (reverse
  50. (call-with-input-string
  51. str
  52. (lambda (port) (texinfo:read-verbatim-body port consumer '())))))
  53. (pass-if-equal '()
  54. (read-verbatim-body-from-string "@end verbatim\n"))
  55. ;; after @verbatim, the current position will always directly after
  56. ;; the newline.
  57. (pass-if-exception "@end verbatim needs a newline"
  58. exception:eof-while-reading-token
  59. (read-verbatim-body-from-string "@end verbatim"))
  60. (pass-if-equal '("@@end verbatim" " NL\n")
  61. (read-verbatim-body-from-string "@@end verbatim\n@end verbatim\n"))
  62. (pass-if-equal '("@@@@faosfasf adsfas " " NL\n" " asf @foo{asdf}" " NL\n")
  63. (read-verbatim-body-from-string
  64. "@@@@faosfasf adsfas \n asf @foo{asdf}\n@end verbatim\n"))
  65. (pass-if-equal '("@end verbatim " " NL\n")
  66. (read-verbatim-body-from-string "@end verbatim \n@end verbatim\n")))
  67. (define texinfo:read-arguments
  68. (@@ (texinfo) read-arguments))
  69. (with-test-prefix "test-read-arguments"
  70. (define (read-arguments-from-string str)
  71. (call-with-input-string
  72. str
  73. (lambda (port) (texinfo:read-arguments port #\}))))
  74. (define (test str expected-res)
  75. (pass-if-equal expected-res
  76. (read-arguments-from-string str)))
  77. (test "}" '())
  78. (test "foo}" '("foo"))
  79. (test "foo,bar}" '("foo" "bar"))
  80. (test " foo , bar }" '("foo" "bar"))
  81. (test " foo , , bar }" '("foo" #f "bar"))
  82. (test "foo,,bar}" '("foo" #f "bar"))
  83. (pass-if-exception "need a } when reading arguments"
  84. exception:eof-while-reading-token
  85. (call-with-input-string
  86. "foo,,bar"
  87. (lambda (port) (texinfo:read-arguments port #\})))))
  88. (define texinfo:complete-start-command
  89. (@@ (texinfo) complete-start-command))
  90. (with-test-prefix "test-complete-start-command"
  91. (define (test command str)
  92. (call-with-input-string
  93. str
  94. (lambda (port)
  95. (call-with-values
  96. (lambda ()
  97. (texinfo:complete-start-command command port))
  98. list))))
  99. (pass-if-equal '(section () EOL-TEXT)
  100. (test 'section "foo bar baz bonzerts"))
  101. (pass-if-equal '(deffnx ((category "Function") (name "foo") (arguments)) EOL-TEXT-ARGS)
  102. (test 'deffnx "Function foo"))
  103. (pass-if-exception "@emph missing a start brace"
  104. exception:wrong-character
  105. (test 'emph "no brace here"))
  106. (pass-if-equal '(emph () INLINE-TEXT)
  107. (test 'emph "{foo bar baz bonzerts"))
  108. (pass-if-equal '(ref ((node "foo bar") (section "baz") (info-file "bonzerts"))
  109. INLINE-ARGS)
  110. (test 'ref "{ foo bar ,, baz, bonzerts}"))
  111. (pass-if-equal '(node ((name "referenced node")) EOL-ARGS)
  112. (test 'node " referenced node\n")))
  113. (define texinfo:read-char-data
  114. (@@ (texinfo) read-char-data))
  115. (define make-texinfo-token cons)
  116. (with-test-prefix "test-read-char-data"
  117. (let* ((code (make-texinfo-token 'START 'code))
  118. (ref (make-texinfo-token 'EMPTY 'ref))
  119. (title (make-texinfo-token 'LINE 'title))
  120. (node (make-texinfo-token 'EMPTY 'node))
  121. (eof-object (with-input-from-string "" read))
  122. (str-handler (lambda (fragment foll-fragment seed)
  123. (if (string-null? foll-fragment)
  124. (cons fragment seed)
  125. (cons* foll-fragment fragment seed)))))
  126. (define (test str expect-eof? preserve-ws? expected-data expected-token)
  127. (call-with-values
  128. (lambda ()
  129. (call-with-input-string
  130. str
  131. (lambda (port)
  132. (texinfo:read-char-data
  133. port expect-eof? preserve-ws? str-handler '()))))
  134. (lambda (seed token)
  135. (let ((result (reverse seed)))
  136. (pass-if-equal expected-data result)
  137. (pass-if-equal expected-token token)))))
  138. ;; add some newline-related tests here
  139. (test "" #t #f '() eof-object)
  140. (test "foo bar baz" #t #f '("foo bar baz") eof-object)
  141. (pass-if-exception "eof reading char data"
  142. exception:eof-while-reading-token
  143. (test "" #f #f '() eof-object))
  144. (test " " #t #f '(" ") eof-object)
  145. (test " @code{foo} " #f #f '(" ") code)
  146. (test " @code" #f #f '(" ") code)
  147. (test " {text here} asda" #f #f '(" ") (make-texinfo-token 'START '*braces*))
  148. (test " blah blah} asda" #f #f '(" blah blah") (make-texinfo-token 'END #f))))
  149. (with-test-prefix "test-texinfo->stexinfo"
  150. (define (test str expected-res)
  151. (pass-if-equal expected-res
  152. (call-with-input-string str texi->stexi)))
  153. (define (try-with-title title str)
  154. (call-with-input-string
  155. (string-append "foo bar baz\n@settitle " title "\n" str)
  156. texi->stexi))
  157. (define (test-with-title title str expected-res)
  158. (test (string-append "foo bar baz\n@settitle " title "\n" str)
  159. expected-res))
  160. (define (test-body str expected-res)
  161. (pass-if-equal str expected-res
  162. (cddr (try-with-title "zog" str))))
  163. (define (list-intersperse src-l elem)
  164. (if (null? src-l) src-l
  165. (let loop ((l (cdr src-l)) (dest (cons (car src-l) '())))
  166. (if (null? l) (reverse dest)
  167. (loop (cdr l) (cons (car l) (cons elem dest)))))))
  168. (define (join-lines . lines)
  169. (apply string-append (list-intersperse lines "\n")))
  170. (pass-if-exception "missing @settitle"
  171. exception:no-settitle
  172. (call-with-input-string "@dots{}\n" texi->stexi))
  173. (test "\\input texinfo\n@settitle my title\n@dots{}\n"
  174. '(texinfo (% (title "my title")) (para (dots))))
  175. (test-with-title "my title" "@dots{}\n"
  176. '(texinfo (% (title "my title")) (para (dots))))
  177. (test-with-title "my title" "@dots{}"
  178. '(texinfo (% (title "my title")) (para (dots))))
  179. (pass-if-exception "arg to @dots{}"
  180. exception:unexpected-arg
  181. (call-with-input-string
  182. "foo bar baz\n@settitle my title\n@dots{arg}"
  183. texi->stexi))
  184. (test-body "@code{arg}"
  185. '((para (code "arg"))))
  186. (test-body "@url{arg}"
  187. '((para (uref (% (url "arg"))))))
  188. (test-body "@url{@@}"
  189. '((para (uref (% (url "@"))))))
  190. (test-body "@url{@var{foo}}"
  191. '((para (uref (% (url (var "foo")))))))
  192. (test-body "@code{ }"
  193. '((para (code))))
  194. (test-body "@code{ @code{} }"
  195. '((para (code (code)))))
  196. (test-body "@code{ abc @code{} }"
  197. '((para (code "abc " (code)))))
  198. (test-body "@code{ arg }"
  199. '((para (code "arg"))))
  200. (test-body "@w{ arg with spaces }"
  201. '((para (w " arg with spaces "))))
  202. (test-body "@acronym{GNU}"
  203. '((para (acronym (% (acronym "GNU"))))))
  204. (test-body "@acronym{GNU, not unix}"
  205. '((para (acronym (% (acronym "GNU")
  206. (meaning "not unix"))))))
  207. (test-body "@acronym{GNU, @acronym{GNU}'s Not Unix}"
  208. '((para (acronym (% (acronym "GNU")
  209. (meaning (acronym (% (acronym "GNU")))
  210. "'s Not Unix"))))))
  211. (test-body "@example\n foo asdf asd sadf asd \n@end example\n"
  212. '((example " foo asdf asd sadf asd ")))
  213. (test-body "@example\n@{\n@}\n@end example\n"
  214. '((example "{\n}")))
  215. (test-body (join-lines
  216. "@quotation"
  217. "@example"
  218. " foo asdf asd sadf asd "
  219. "@end example"
  220. "@end quotation"
  221. "")
  222. '((quotation (example " foo asdf asd sadf asd "))))
  223. (test-body (join-lines
  224. "@quotation"
  225. "@example"
  226. " foo asdf @var{asd} sadf asd "
  227. "@end example"
  228. "@end quotation"
  229. "")
  230. '((quotation (example " foo asdf " (var "asd") " sadf asd "))))
  231. (test-body (join-lines
  232. "@quotation"
  233. "@example"
  234. " foo asdf @var{asd} sadf asd "
  235. ""
  236. "not in new para, this is an example"
  237. "@end example"
  238. "@end quotation"
  239. "")
  240. '((quotation
  241. (example
  242. " foo asdf " (var "asd")
  243. " sadf asd \n\nnot in new para, this is an example"))))
  244. (test-body (join-lines
  245. "@titlepage"
  246. "@quotation"
  247. " foo asdf @var{asd} sadf asd "
  248. ""
  249. "should be in new para"
  250. "@end quotation"
  251. "@end titlepage"
  252. "")
  253. '((titlepage
  254. (quotation (para "foo asdf " (var "asd") " sadf asd")
  255. (para "should be in new para")))))
  256. (test-body (join-lines
  257. ""
  258. "@titlepage"
  259. ""
  260. "@quotation"
  261. " foo asdf @var{asd} sadf asd "
  262. ""
  263. "should be in new para"
  264. ""
  265. ""
  266. "@end quotation"
  267. "@end titlepage"
  268. ""
  269. "@bye"
  270. ""
  271. "@foo random crap at the end"
  272. "")
  273. '((titlepage
  274. (quotation (para "foo asdf " (var "asd") " sadf asd")
  275. (para "should be in new para")))))
  276. (test-body (join-lines
  277. ""
  278. "random notes"
  279. "@quotation"
  280. " foo asdf @var{asd} sadf asd "
  281. ""
  282. "should be in new para"
  283. ""
  284. ""
  285. "@end quotation"
  286. ""
  287. " hi mom"
  288. "")
  289. '((para "random notes")
  290. (quotation (para "foo asdf " (var "asd") " sadf asd")
  291. (para "should be in new para"))
  292. (para "hi mom")))
  293. (test-body (join-lines
  294. "@enumerate"
  295. "@item one"
  296. "@item two"
  297. "@item three"
  298. "@end enumerate"
  299. )
  300. '((enumerate (item (para "one"))
  301. (item (para "two"))
  302. (item (para "three")))))
  303. (test-body (join-lines
  304. "@enumerate 44"
  305. "@item one"
  306. "@item two"
  307. "@item three"
  308. "@end enumerate"
  309. )
  310. '((enumerate (% (start "44"))
  311. (item (para "one"))
  312. (item (para "two"))
  313. (item (para "three")))))
  314. (pass-if-exception "bad enumerate formatter"
  315. exception:bad-enumerate
  316. (try-with-title "foo" (join-lines
  317. "@enumerate string"
  318. "@item one"
  319. "@item two"
  320. "@item three"
  321. "@end enumerate"
  322. )))
  323. (pass-if-exception "bad itemize formatter"
  324. exception:bad-enumerate
  325. (try-with-title "foo" (join-lines
  326. "@itemize string"
  327. "@item one"
  328. "@item two"
  329. "@item three"
  330. "@end itemize"
  331. )))
  332. (test-body (join-lines
  333. "@itemize" ;; no formatter, should default to bullet
  334. "@item one"
  335. "@item two"
  336. "@item three"
  337. "@end itemize"
  338. )
  339. '((itemize (% (bullet (bullet)))
  340. (item (para "one"))
  341. (item (para "two"))
  342. (item (para "three")))))
  343. (test-body (join-lines
  344. "@itemize @bullet"
  345. "@item one"
  346. "@item two"
  347. "@item three"
  348. "@end itemize"
  349. )
  350. '((itemize (% (bullet (bullet)))
  351. (item (para "one"))
  352. (item (para "two"))
  353. (item (para "three")))))
  354. (test-body (join-lines
  355. "@itemize -"
  356. "@item one"
  357. "@item two"
  358. "@item three"
  359. "@end itemize"
  360. )
  361. '((itemize (% (bullet "-"))
  362. (item (para "one"))
  363. (item (para "two"))
  364. (item (para "three")))))
  365. (test-body (join-lines
  366. "@table @code"
  367. "preliminary text -- should go in a pre-item para"
  368. "@item one"
  369. "item one text"
  370. "@item two"
  371. "item two text"
  372. ""
  373. "includes a paragraph"
  374. "@item three"
  375. "@end itemize"
  376. )
  377. '((table (% (formatter (code)))
  378. (para "preliminary text -- should go in a pre-item para")
  379. (entry (% (heading "one"))
  380. (para "item one text"))
  381. (entry (% (heading "two"))
  382. (para "item two text")
  383. (para "includes a paragraph"))
  384. (entry (% (heading "three"))))))
  385. (test-body (join-lines
  386. "@chapter @code{foo} bar"
  387. "text that should be in a para"
  388. )
  389. '((chapter (code "foo") " bar")
  390. (para "text that should be in a para")))
  391. (test-body (join-lines
  392. "@deffnx Method foo bar @code{baz}"
  393. "text that should be in a para"
  394. )
  395. '((deffnx (% (category "Method")
  396. (name "foo")
  397. (arguments "bar " (code "baz"))))
  398. (para "text that should be in a para")))
  399. (test-body "@pxref{Locales, @code{setlocale}}"
  400. '((para (pxref (% (node "Locales")
  401. (name (code "setlocale")))))))
  402. (test-body "Like this---e.g.@:, at colon."
  403. '((para "Like this---e.g.:, at colon.")))
  404. )