cli.scm 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. ;;; Disarchive
  2. ;;; Copyright © 2022 Timothy Sample <samplet@ngyro.com>
  3. ;;;
  4. ;;; This file is part of Disarchive.
  5. ;;;
  6. ;;; Disarchive is free software: you can redistribute it and/or modify
  7. ;;; it under the terms of the GNU General Public License as published by
  8. ;;; the Free Software Foundation, either version 3 of the License, or
  9. ;;; (at your option) any later version.
  10. ;;;
  11. ;;; Disarchive 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
  14. ;;; GNU General Public License for more details.
  15. ;;;
  16. ;;; You should have received a copy of the GNU General Public License
  17. ;;; along with Disarchive. If not, see <http://www.gnu.org/licenses/>.
  18. (use-modules (disarchive)
  19. (disarchive assemblers)
  20. (disarchive config)
  21. (disarchive digests)
  22. (disarchive utils)
  23. (ice-9 binary-ports)
  24. (ice-9 popen)
  25. (ice-9 textual-ports)
  26. (rnrs bytevectors)
  27. (srfi srfi-64))
  28. (define status-ok? (compose zero? status:exit-val))
  29. (define status-error? (compose not status-ok?))
  30. (define data
  31. (or (getenv "DISARCHIVE_TEST_DATA")
  32. (error "The DISARCHIVE_TEST_DATA variable is not set")))
  33. (define (capture/error cli)
  34. (let* ((cli* (string-append "2>&1 1>/dev/null " cli))
  35. (port (open-pipe cli* OPEN_READ))
  36. (output (get-string-all port)))
  37. (unless (status-error? (close-pipe port))
  38. (error "Program exited normally" cli*))
  39. output))
  40. (define (capture/ok cli)
  41. (let* ((port (open-pipe cli OPEN_READ))
  42. (output (get-string-all port)))
  43. (unless (status-ok? (close-pipe port))
  44. (error "Program exited abnormally" cli))
  45. output))
  46. (define (file=? file1 file2)
  47. (let ((bv1 (call-with-input-file file1 get-bytevector-all))
  48. (bv2 (call-with-input-file file2 get-bytevector-all)))
  49. (bytevector=? bv1 bv2)))
  50. (define (specification=? spec1 spec2)
  51. (let* ((bp1 (specification->blueprint spec1))
  52. (digest1 (blueprint-digest bp1))
  53. (bp2 (specification->blueprint spec2))
  54. (digest2 (blueprint-digest bp2)))
  55. (equal? digest1 digest2)))
  56. (test-begin "cli")
  57. ;; The root command
  58. (test-assert "Errors on bogus option"
  59. (status-error? (system "disarchive --foo")))
  60. (test-assert "Prints usage on option error"
  61. (let ((output (capture/error "disarchive --foo")))
  62. (or (string-contains output "Usage")
  63. (string-contains output "usage"))))
  64. (test-assert "Errors on bogus command"
  65. (status-error? (system "disarchive foo")))
  66. (test-assert "Prints usage on bogus command"
  67. (let ((output (capture/error "disarchive foo")))
  68. (or (string-contains output "Usage")
  69. (string-contains output "usage"))))
  70. (test-assert "Errors when given no options"
  71. (status-error? (system "disarchive")))
  72. (test-assert "Accepts --version"
  73. (status-ok? (system "disarchive --version")))
  74. (test-assert "Version includes package name and version"
  75. (let ((version (capture/ok "disarchive --version")))
  76. (and (string-contains version %package-name)
  77. (string-contains version %version))))
  78. (test-assert "Accepts --help"
  79. (status-ok? (system "disarchive --help")))
  80. ;; The assemble subcommand
  81. (test-assert "Accepts --help (assemble)"
  82. (status-ok? (system "disarchive assemble --help")))
  83. (test-assert "Accepts --version (assemble)"
  84. (status-ok? (system "disarchive assemble --version")))
  85. (test-assert "Errors on bogus option (assemble)"
  86. (status-error? (system "disarchive assemble --foo")))
  87. (test-assert "Prints usage on option error (assemble)"
  88. (let ((output (capture/error "disarchive assemble --foo")))
  89. (and (string-contains output "assemble")
  90. (or (string-contains output "Usage")
  91. (string-contains output "usage")))))
  92. (test-assert "Errors on missing options (assemble)"
  93. (status-error? (system "disarchive assemble")))
  94. (test-assert "Prints usage on missing options (assemble)"
  95. (let ((output (capture/error "disarchive assemble")))
  96. (and (string-contains output "assemble")
  97. (or (string-contains output "Usage")
  98. (string-contains output "usage")))))
  99. (test-assert "Assembles from stdin to stdout"
  100. (let ((spec (string-append data "/test-archive.da"))
  101. (directory (string-append data "/test-archive"))
  102. (expected (string-append data "/test-archive.tar")))
  103. (call-with-temporary-output-file
  104. (lambda (filename port)
  105. (let ((status (with-input-from-file spec
  106. (lambda ()
  107. (with-output-to-port port
  108. (lambda ()
  109. (system* "disarchive" "assemble"
  110. directory "-")))))))
  111. (close-port port)
  112. (and (status-ok? status)
  113. (file=? filename expected)))))))
  114. (test-assert "Assembles from stdin to file"
  115. (let ((spec (string-append data "/test-archive.da"))
  116. (directory (string-append data "/test-archive"))
  117. (expected (string-append data "/test-archive.tar")))
  118. (call-with-temporary-output-file
  119. (lambda (filename port)
  120. (close-port port)
  121. (let ((status (with-input-from-file spec
  122. (lambda ()
  123. (system* "disarchive" "assemble"
  124. "-o" filename directory "-")))))
  125. (and (status-ok? status)
  126. (file=? filename expected)))))))
  127. (test-assert "Assembles from file to stdout"
  128. (let ((spec (string-append data "/test-archive.da"))
  129. (directory (string-append data "/test-archive"))
  130. (expected (string-append data "/test-archive.tar")))
  131. (call-with-temporary-output-file
  132. (lambda (filename port)
  133. (let ((status (with-output-to-port port
  134. (lambda ()
  135. (system* "disarchive" "assemble"
  136. directory spec)))))
  137. (close-port port)
  138. (and (status-ok? status)
  139. (file=? filename expected)))))))
  140. (test-assert "Assembles from file to file"
  141. (let ((spec (string-append data "/test-archive.da"))
  142. (directory (string-append data "/test-archive"))
  143. (expected (string-append data "/test-archive.tar")))
  144. (call-with-temporary-output-file
  145. (lambda (filename port)
  146. (close-port port)
  147. (and (status-ok? (system* "disarchive" "assemble"
  148. "-o" filename directory spec))
  149. (file=? filename expected))))))
  150. ;; The disassemble subcommand
  151. (test-assert "Accepts --help (disassemble)"
  152. (status-ok? (system "disarchive disassemble --help")))
  153. (test-assert "Accepts --version (disassemble)"
  154. (status-ok? (system "disarchive disassemble --version")))
  155. (test-assert "Errors on bogus option (disassemble)"
  156. (status-error? (system "disarchive disassemble --foo")))
  157. (test-assert "Prints usage on option error (disassemble)"
  158. (let ((output (capture/error "disarchive disassemble --foo")))
  159. (and (string-contains output "disassemble")
  160. (or (string-contains output "Usage")
  161. (string-contains output "usage")))))
  162. (test-assert "Errors on missing options (disassemble)"
  163. (status-error? (system "disarchive disassemble")))
  164. (test-assert "Prints usage on missing options (disassemble)"
  165. (let ((output (capture/error "disarchive disassemble")))
  166. (and (string-contains output "disassemble")
  167. (or (string-contains output "Usage")
  168. (string-contains output "usage")))))
  169. (test-assert "Disassembles from file to stdout"
  170. (let ((archive (string-append data "/test-archive.tar"))
  171. (expected (string-append data "/test-archive.da")))
  172. (call-with-temporary-output-file
  173. (lambda (filename port)
  174. (let ((status (with-output-to-port port
  175. (lambda ()
  176. (system* "disarchive" "disassemble" archive)))))
  177. (close-port port)
  178. (and (status-ok? status)
  179. (specification=? filename expected)))))))
  180. (test-assert "Disassembles from file to file"
  181. (let ((archive (string-append data "/test-archive.tar"))
  182. (expected (string-append data "/test-archive.da")))
  183. (call-with-temporary-output-file
  184. (lambda (filename port)
  185. (close-port port)
  186. (and (status-ok? (system* "disarchive" "disassemble"
  187. "-o" filename archive))
  188. (specification=? filename expected))))))
  189. (test-equal "Disassembles with basename by default"
  190. "test-archive.tar"
  191. (let ((archive (string-append data "/test-archive.tar")))
  192. (call-with-temporary-output-file
  193. (lambda (filename port)
  194. (close-port port)
  195. (and (status-ok? (system* "disarchive" "disassemble"
  196. "-o" filename archive))
  197. (let ((bp (specification->blueprint filename)))
  198. (blueprint-name bp)))))))
  199. (test-equal "Disassembles with a given name"
  200. "foobar.tar"
  201. (let ((archive (string-append data "/test-archive.tar")))
  202. (call-with-temporary-output-file
  203. (lambda (filename port)
  204. (close-port port)
  205. (and (status-ok? (system* "disarchive" "disassemble"
  206. "-n" "foobar.tar" "-o" filename archive))
  207. (let ((bp (specification->blueprint filename)))
  208. (blueprint-name bp)))))))
  209. (test-end "cli")