PageRenderTime 54ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/site/ucw-boxset/dependencies/rfc2388/test/test.lisp

https://github.com/vikram/lisplibraries
Lisp | 255 lines | 212 code | 21 blank | 22 comment | 3 complexity | 8e49036e63d3a77aca6606205a586cee MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-2.1, CC-BY-SA-3.0, LGPL-3.0, BSD-3-Clause, GPL-2.0
  1. ;; -*- lisp -*-
  2. (in-package :rfc2388.test)
  3. (def-suite :rfc2388)
  4. (in-suite :rfc2388)
  5. (defparameter *test-data-dir*
  6. (make-pathname :directory
  7. (append (pathname-directory
  8. #.(asdf:component-pathname (asdf:find-system :rfc2388.test)))
  9. '("test" "data"))))
  10. (defun data-file (filename)
  11. (merge-pathnames filename *test-data-dir*))
  12. (test parse-key-values
  13. (macrolet ((test-key-values (bind string &body body)
  14. `(destructuring-bind ,bind
  15. (rfc2388::parse-key-values ,string)
  16. ,@body)))
  17. (test-key-values ((foo . bar)) "foo=bar"
  18. (is (string= "foo" foo))
  19. (is (string= "bar" bar)))
  20. (test-key-values ((one . two) (three . four))
  21. "one=two;three=four"
  22. (is (string= "one" one))
  23. (is (string= "two" two))
  24. (is (string= "three" three))
  25. (is (string= "four" four)))
  26. (test-key-values ((k1 . v1) (k2 . v2) (k3 . v3) (k4 . v4))
  27. "1=\"2\";1=2 ;1=2 ; 1=2"
  28. (is-true (every (lambda (key)
  29. (string= "1" key))
  30. (list k1 k2 k3 k4)))
  31. (is-true (every (lambda (value)
  32. (string= "2" value))
  33. (list v1 v2 v3 v4))))))
  34. (test parse-header-value
  35. (multiple-value-bind (form-data attributes)
  36. (rfc2388::parse-header-value "form-data")
  37. (is (string= "form-data" form-data))
  38. (is (null attributes)))
  39. (multiple-value-bind (form-data attributes)
  40. (rfc2388::parse-header-value "form-data;")
  41. (is (string= "form-data" form-data))
  42. (is (null attributes)))
  43. (multiple-value-bind (form-data attributes)
  44. (rfc2388::parse-header-value "form-data; a=b")
  45. (is (string= "form-data" form-data))
  46. (is (string= "a" (caar attributes)))
  47. (is (string= "b" (cdar attributes))))
  48. (multiple-value-bind (form-data attributes)
  49. (rfc2388::parse-header-value "form-data; a=b ; c=\"d\"")
  50. (is (string= "form-data" form-data))
  51. (destructuring-bind ((a . b) (c . d))
  52. attributes
  53. (is (string= "a" a))
  54. (is (string= "b" b))
  55. (is (string= "c" c))
  56. (is (string= "d" d)))))
  57. (test as-ascii-char
  58. (is (char= #\Space (rfc2388::as-ascii-char 32)))
  59. (is (char= #\Tab (rfc2388::as-ascii-char 9)))
  60. (is (char= #\! (rfc2388::as-ascii-char 33)))
  61. (is (char= #\: (rfc2388::as-ascii-char 58)))
  62. (is (char= #\a (rfc2388::as-ascii-char 97)))
  63. (is (char= #\A (rfc2388::as-ascii-char 65))))
  64. (test empty-data
  65. (with-input-from-file (mime (data-file "mime1") :element-type '(unsigned-byte 8))
  66. (is-true
  67. (rfc2388::read-until-next-boundary mime
  68. (rfc2388::ascii-string-to-boundary-array "12345678")
  69. (lambda (byte)
  70. (declare (ignore byte))
  71. (fail)))))
  72. (with-input-from-file (mime (data-file "mime2") :element-type '(unsigned-byte 8))
  73. (is-false
  74. (rfc2388::read-until-next-boundary mime
  75. (rfc2388::ascii-string-to-boundary-array "12345678")
  76. (lambda (byte)
  77. (fail "Read char byte ~D (~C), why?" byte (code-char byte)))))))
  78. (test hello-world
  79. (with-output-to-string (hello-world)
  80. (with-input-from-file (mime (data-file "mime3") :element-type '(unsigned-byte 8))
  81. (is-true
  82. (rfc2388::read-until-next-boundary mime
  83. (rfc2388::ascii-string-to-boundary-array "12345678")
  84. (lambda (byte)
  85. (write-char (code-char byte) hello-world))))
  86. (is (string= "hello, world!" (get-output-stream-string hello-world)))))
  87. (with-output-to-string (hello-world)
  88. (with-input-from-file (mime (data-file "mime4") :element-type '(unsigned-byte 8))
  89. (is-true
  90. (rfc2388::read-until-next-boundary mime
  91. (rfc2388::ascii-string-to-boundary-array "12345678")
  92. (lambda (byte)
  93. (declare (ignore byte))
  94. (fail))))
  95. (is-false
  96. (rfc2388::read-until-next-boundary mime
  97. (rfc2388::ascii-string-to-boundary-array "12345678")
  98. (lambda (byte)
  99. (write-char (code-char byte) hello-world))))
  100. (is (string= "
  101. hello, world!" (get-output-stream-string hello-world))))))
  102. (test parse-header
  103. (with-input-from-file (header (data-file "header1")
  104. :element-type '(unsigned-byte 8))
  105. (multiple-value-bind (found-header header-name header-value)
  106. (rfc2388::read-next-header header)
  107. (is-true found-header)
  108. (is (string= "foo" header-name))
  109. (is (string= "bar" header-value)))
  110. (is-false (rfc2388::read-next-header header))))
  111. (defun simple-test-callback (partial-mime-part)
  112. (setf (content partial-mime-part)
  113. (make-array 10
  114. :element-type '(unsigned-byte 8)
  115. :adjustable t
  116. :fill-pointer 0))
  117. (values
  118. (lambda (byte)
  119. (vector-push-extend byte (content partial-mime-part)))
  120. (lambda (mime-part)
  121. mime-part)))
  122. (defun string-to-vector (string)
  123. (map 'vector #'char-code string))
  124. (test read-mime
  125. (with-input-from-file (mime (data-file "mime5") :element-type '(unsigned-byte 8))
  126. (read-mime mime "--AaB03x" #'simple-test-callback)
  127. (pass))
  128. (with-input-from-file (mime (data-file "mime5") :element-type '(unsigned-byte 8))
  129. (let ((parts (read-mime mime "--AaB03x" #'simple-test-callback)))
  130. (let ((larry (first parts)))
  131. (is (equalp (content larry) (string-to-vector "Larry"))))
  132. (let ((file1 (second parts)))
  133. (is (equalp (content file1) (string-to-vector "file1.txt")))
  134. (is (string= "text/plain" (content-type (second parts)))))
  135. (is (= 2 (length parts))))))
  136. (test read-mime-multipart
  137. (with-input-from-file (mime (data-file "mime6") :element-type '(unsigned-byte 8))
  138. (read-mime mime "AaB03x" #'simple-test-callback)
  139. (pass))
  140. (with-input-from-file (mime (data-file "mime6") :element-type '(unsigned-byte 8))
  141. (let ((parts (read-mime mime "AaB03x" #'simple-test-callback)))
  142. (is (= 3 (length parts)))
  143. (destructuring-bind (file1 file2 larry)
  144. parts
  145. (is (equalp (content larry) (string-to-vector "Larry")))
  146. (is (string= "form-data" (header-value (get-header larry "Content-Disposition"))))
  147. (is (equalp (content file1) (string-to-vector "file1.txt")))
  148. (is (equalp (content file2) (string-to-vector "file2.gif")))))))
  149. (test read-mime-multipart2
  150. (with-input-from-file (mime (data-file "mime7") :element-type '(unsigned-byte 8))
  151. (let ((parts (read-mime mime "AaB03x" #'simple-test-callback)))
  152. (is (= 1 (length parts)))
  153. (destructuring-bind (files)
  154. parts
  155. (is (string= "form-data" (header-value (get-header files "Content-Disposition"))))
  156. (is (equalp (content files) (string-to-vector "----AaB03")))))))
  157. (test read-binary
  158. (with-input-from-file (mime (data-file "mime8") :element-type '(unsigned-byte 8))
  159. (let ((parts (read-mime mime "----------hUrrH2HCA6fHrlQsvCv5qD" #'simple-test-callback)))
  160. (is (= 4 (length parts)))
  161. (destructuring-bind (s f a file) parts
  162. (is (equalp (string-to-vector "wTWkJQflmGAAAtiuGQjZfdliukKmDMrVxzXziwGq") (content s)))
  163. (is (equalp (string-to-vector "NkPeoCRHHdAUgcTAWYkw") (content f)))
  164. (is (equalp (string-to-vector "xovkAWwneq") (content a))) ; Won't do harm, might be useful.
  165. (is (string= "form-data" (header-value (get-header file "Content-Disposition"))))
  166. (is (string= "application/x-macbinary" (header-value (get-header file "Content-Type"))))
  167. (is (equalp (content file)
  168. (make-array 512 :element-type '(unsigned-byte 8)
  169. :initial-contents (nconc (loop for x from 0 to 255 collecting x)
  170. (loop for x from 255 downto 0 collecting x)))))))))
  171. (test random-junk
  172. (for-all ((random-byte-buffer (gen-buffer :length (gen-integer :min (expt 2 0) :max (expt 2 4))
  173. :elements (gen-one-element
  174. (char-code #\-)
  175. 10
  176. 13
  177. (char-code #\Space)))
  178. (not (search "----------hUrrH2HCA6fHrlQsvCv5qD"
  179. random-byte-buffer))))
  180. (with-output-to-file (mime (data-file "mime9")
  181. :element-type '(unsigned-byte 8)
  182. :if-exists :supersede)
  183. (flet ((%line (data)
  184. (write-sequence (string-to-vector data) mime)
  185. (write-byte 13 mime)
  186. (write-byte 10 mime)))
  187. (%line "------------hUrrH2HCA6fHrlQsvCv5qD")
  188. (%line "Content-Disposition: form-data; name=\"IujzYaQDEj\"; filename=\"foo.bin\"") ;
  189. (%line "Content-Type: application/octet-stream")
  190. (%line "")
  191. (write-sequence random-byte-buffer mime)
  192. (write-byte 13 mime)
  193. (write-byte 10 mime)
  194. (%line "------------hUrrH2HCA6fHrlQsvCv5qD--")))
  195. (with-input-from-file (mime (data-file "mime9") :element-type '(unsigned-byte 8))
  196. (let ((parts (read-mime mime "----------hUrrH2HCA6fHrlQsvCv5qD" #'simple-test-callback)))
  197. (is (= 1 (length parts)))
  198. (destructuring-bind (file) parts
  199. (is (= (length random-byte-buffer) (length (content file)))
  200. "Wrote ~D bytes, got ~D back." (length random-byte-buffer) (length (content file)))
  201. (loop
  202. for index upfrom 0 below (min (length random-byte-buffer)
  203. (length (content file)))
  204. do (when (/= (aref random-byte-buffer index)
  205. (aref (content file) index))
  206. (fail
  207. "Bytes at offset ~D differ (length: ~D; on-disk: ~D; returned: ~D)"
  208. index
  209. (length random-byte-buffer)
  210. (aref random-byte-buffer index)
  211. (aref (content file) index))))
  212. (is (string= "form-data" (header-value (get-header file "Content-Disposition"))))
  213. (is (string= "application/octet-stream" (header-value (get-header file "Content-Type")))))))))
  214. ;; Copyright (c) 2003 Janis Dzerins
  215. ;; Copyright (c) 2005 Edward Marco Baringer
  216. ;;
  217. ;; Redistribution and use in source and binary forms, with or without
  218. ;; modification, are permitted provided that the following conditions
  219. ;; are met:
  220. ;; 1. Redistributions of source code must retain the above copyright
  221. ;; notice, this list of conditions and the following disclaimer.
  222. ;; 2. Redistributions in binary form must reproduce the above copyright
  223. ;; notice, this list of conditions and the following disclaimer in the
  224. ;; documentation and/or other materials provided with the distribution.
  225. ;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  226. ;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  227. ;; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  228. ;; IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  229. ;; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  230. ;; NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  231. ;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  232. ;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  233. ;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  234. ;; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.