func-test.el 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. (eval-when-compile (require 'cl))
  2. (require 'ert)
  3. (require 'ein-notebooklist)
  4. (require 'wid-edit)
  5. (require 'ein-testing)
  6. (require 'ein-testing-cell)
  7. (let ((backend (getenv "EL_REQUEST_BACKEND")))
  8. (when (and backend (not (equal backend "")))
  9. (setq request-backend (intern backend))
  10. (message "Using request-backend = %S" request-backend)))
  11. (ein:setq-if-not ein:testing-dump-file-log "func-test-batch-log.log")
  12. (ein:setq-if-not ein:testing-dump-file-messages "func-test-batch-messages.log")
  13. (setq message-log-max t)
  14. (defvar ein:testing-port 8889)
  15. (defun ein:testing-wait-until (predicate &optional predargs max-count)
  16. "Wait until PREDICATE function returns non-`nil'.
  17. PREDARGS is argument list for the PREDICATE function.
  18. Make MAX-COUNT larger \(default 50) to wait longer before timeout."
  19. (ein:log 'debug "TESTING-WAIT-UNTIL start")
  20. (unless (setq max-count 50))
  21. (unless (loop repeat max-count
  22. when (apply predicate predargs)
  23. return t
  24. ;; borrowed from `deferred:sync!':
  25. do (sit-for 0.05)
  26. do (sleep-for 0.05))
  27. (error "Timeout"))
  28. (ein:log 'debug "TESTING-WAIT-UNTIL end"))
  29. (defun ein:testing-get-notebook-by-name (url-or-port notebook-name)
  30. (ein:log 'debug "TESTING-GET-NOTEBOOK-BY-NAME start")
  31. ;; Kill notebook list buffer here to make sure next
  32. ;; `ein:testing-wait-until' works properly.
  33. (kill-buffer (ein:notebooklist-get-buffer url-or-port))
  34. (with-current-buffer (ein:notebooklist-open url-or-port nil)
  35. (ein:testing-wait-until (lambda () ein:%notebooklist%))
  36. (prog1
  37. (ein:notebooklist-open-notebook-by-name notebook-name)
  38. (ein:log 'debug "TESTING-GET-NOTEBOOK-BY-NAME end"))))
  39. (defun ein:testing-get-untitled0-or-create (url-or-port)
  40. (ein:log 'debug "TESTING-GET-UNTITLED0-OR-CREATE start")
  41. (let ((notebook (ein:testing-get-notebook-by-name url-or-port "Untitled0")))
  42. (if notebook
  43. (progn (ein:log 'debug
  44. "TESTING-GET-UNTITLED0-OR-CREATE notebook already exists")
  45. notebook)
  46. (ein:log 'debug
  47. "TESTING-GET-UNTITLED0-OR-CREATE creating notebook")
  48. (let ((created nil))
  49. (ein:notebooklist-new-notebook url-or-port
  50. (lambda (&rest -ignore-)
  51. (setq created t)))
  52. (ein:testing-wait-until (lambda () created)))
  53. (prog1
  54. (ein:testing-get-notebook-by-name url-or-port "Untitled0")
  55. (ein:log 'debug "TESTING-GET-UNTITLED0-OR-CREATE end")))))
  56. (defvar ein:notebooklist-after-open-hook nil)
  57. (defadvice ein:notebooklist-url-retrieve-callback
  58. (after ein:testing-notebooklist-url-retrieve-callback activate)
  59. "Advice to add `ein:notebooklist-after-open-hook'."
  60. (run-hooks 'ein:notebooklist-after-open-hook))
  61. (defun ein:testing-delete-notebook-by-name (url-or-port notebook-name)
  62. (ein:log 'debug "TESTING-DELETE-NOTEBOOK-BY-NAME start")
  63. (lexical-let (called-p)
  64. (let ((ein:notebooklist-after-open-hook
  65. (list (lambda () (setq called-p t)))))
  66. (with-current-buffer (ein:notebooklist-open url-or-port nil)
  67. (ein:testing-wait-until (lambda () ein:%notebooklist%))
  68. (save-excursion
  69. (goto-char (point-min))
  70. (search-forward notebook-name)
  71. (move-beginning-of-line 1)
  72. (search-forward "Delete")
  73. (flet ((y-or-n-p (ignore) t))
  74. (widget-button-press (point))))
  75. (ein:testing-wait-until (lambda () called-p))
  76. (ein:log 'debug "TESTING-DELETE-NOTEBOOK-BY-NAME end")))))
  77. (ert-deftest ein:testing-get-untitled0-or-create ()
  78. (ein:log 'verbose "ERT TESTING-GET-UNTITLED0-OR-CREATE start")
  79. (let ((notebook (ein:testing-get-untitled0-or-create ein:testing-port)))
  80. (ein:testing-wait-until
  81. (lambda () (ein:aand (ein:$notebook-kernel notebook)
  82. (ein:kernel-live-p it))))
  83. (with-current-buffer (ein:notebook-buffer notebook)
  84. (should (equal (ein:$notebook-notebook-name ein:%notebook%)
  85. "Untitled0"))))
  86. (ein:log 'verbose "ERT TESTING-GET-UNTITLED0-OR-CREATE end"))
  87. (ert-deftest ein:testing-delete-untitled0 ()
  88. (ein:log 'verbose "ERT TESTING-DELETE-UNTITLED0 start")
  89. (loop
  90. for i from 0 to 1
  91. do (ein:log 'debug "ERT TESTING-DELETE-UNTITLED0 i=%s" i)
  92. do (ein:log 'debug "ERT TESTING-DELETE-UNTITLED0 creating notebook")
  93. do (let ((notebook (ein:testing-get-untitled0-or-create ein:testing-port)))
  94. (ein:testing-wait-until
  95. (lambda () (ein:aand (ein:$notebook-kernel notebook)
  96. (ein:kernel-live-p it)))))
  97. do (ein:log 'debug "ERT TESTING-DELETE-UNTITLED0 delete notebook")
  98. do (ein:testing-delete-notebook-by-name ein:testing-port "Untitled0")
  99. do (ein:log 'debug
  100. "ERT TESTING-DELETE-UNTITLED0 check the notebook is delete")
  101. do (let ((num-notebook
  102. (length (ein:testing-get-notebook-by-name ein:testing-port
  103. "Untitled0"))))
  104. (should (= num-notebook 0))))
  105. (ein:log 'debug "ERT TESTING-DELETE-UNTITLED0 end"))
  106. (ert-deftest ein:notebook-execute-current-cell-simple ()
  107. (let ((notebook (ein:testing-get-untitled0-or-create ein:testing-port)))
  108. (ein:testing-wait-until
  109. (lambda () (ein:aand (ein:$notebook-kernel notebook)
  110. (ein:kernel-live-p it))))
  111. (with-current-buffer (ein:notebook-buffer notebook)
  112. (call-interactively #'ein:worksheet-insert-cell-below)
  113. (insert "a = 100\na")
  114. (let ((cell (call-interactively #'ein:worksheet-execute-cell)))
  115. (ein:testing-wait-until (lambda () (not (oref cell :running)))))
  116. ;; (message "%s" (buffer-string))
  117. (save-excursion
  118. (should (search-forward-regexp "Out \\[[0-9]+\\]" nil t))
  119. (should (search-forward "100" nil t))))))
  120. (defun ein:testing-image-type (image)
  121. "Return the type of IMAGE.
  122. See the definition of `create-image' for how it works."
  123. (assert (and (listp image) (eq (car image) 'image)) nil
  124. "%S is not an image." image)
  125. (plist-get (cdr image) :type))
  126. (ert-deftest ein:notebook-execute-current-cell-pyout-image ()
  127. (let ((notebook (ein:testing-get-untitled0-or-create ein:testing-port)))
  128. (ein:testing-wait-until
  129. (lambda () (ein:aand (ein:$notebook-kernel notebook)
  130. (ein:kernel-live-p it))))
  131. (with-current-buffer (ein:notebook-buffer notebook)
  132. (call-interactively #'ein:worksheet-insert-cell-below)
  133. ;; Use IPython.core.display rather than IPython.display to
  134. ;; test it with older (< 0.13) IPython.
  135. (insert (concat "from IPython.core.display import SVG\n"
  136. (format "SVG(data=\"\"\"%s\"\"\")"
  137. ein:testing-example-svg)))
  138. (let ((cell (call-interactively #'ein:worksheet-execute-cell)))
  139. ;; It seems in this case, watching `:running' does not work
  140. ;; well sometimes. Probably "output reply" (iopub) comes
  141. ;; before "execute reply" in this case.
  142. (ein:testing-wait-until (lambda () (oref cell :outputs)))
  143. ;; This cell has only one input
  144. (should (= (length (oref cell :outputs)) 1))
  145. ;; This output is a SVG image
  146. (let ((out (nth 0 (oref cell :outputs))))
  147. (should (equal (plist-get out :output_type) "pyout"))
  148. (should (plist-get out :svg))))
  149. ;; Check the actual output in the buffer:
  150. (save-excursion
  151. (should (search-forward-regexp "Out \\[[0-9]+\\]" nil t))
  152. (should (= (forward-line) 0))
  153. (if (image-type-available-p 'svg)
  154. (let ((image (get-text-property (point) 'display)))
  155. (should (eq (ein:testing-image-type image) 'svg)))
  156. (ein:log 'info
  157. "Skipping image check as SVG image type is not available."))))))
  158. (ert-deftest ein:notebook-execute-current-cell-stream ()
  159. (let ((notebook (ein:testing-get-untitled0-or-create ein:testing-port)))
  160. (ein:testing-wait-until
  161. (lambda () (ein:aand (ein:$notebook-kernel notebook)
  162. (ein:kernel-live-p it))))
  163. (with-current-buffer (ein:notebook-buffer notebook)
  164. (call-interactively #'ein:worksheet-insert-cell-below)
  165. (insert "print 'Hello'")
  166. (let ((cell (call-interactively #'ein:worksheet-execute-cell)))
  167. (ein:testing-wait-until (lambda () (not (oref cell :running)))))
  168. (save-excursion
  169. (should-not (search-forward-regexp "Out \\[[0-9]+\\]" nil t))
  170. (should (search-forward-regexp "^Hello$" nil t))))))
  171. (ert-deftest ein:notebook-execute-current-cell-question ()
  172. (let ((notebook (ein:testing-get-untitled0-or-create ein:testing-port)))
  173. (ein:testing-wait-until
  174. (lambda () (ein:aand (ein:$notebook-kernel notebook)
  175. (ein:kernel-live-p it))))
  176. (with-current-buffer (ein:notebook-buffer notebook)
  177. (call-interactively #'ein:worksheet-insert-cell-below)
  178. (insert "range?")
  179. (let ((cell (call-interactively #'ein:worksheet-execute-cell)))
  180. (ein:testing-wait-until (lambda () (not (oref cell :running)))))
  181. (with-current-buffer (get-buffer (ein:$notebook-pager notebook))
  182. (should (search-forward "Docstring:\nrange"))))))
  183. (ert-deftest ein:notebook-request-help ()
  184. (let ((notebook (ein:testing-get-untitled0-or-create ein:testing-port)))
  185. (ein:testing-wait-until
  186. (lambda () (ein:aand (ein:$notebook-kernel notebook)
  187. (ein:kernel-live-p it))))
  188. (with-current-buffer (ein:notebook-buffer notebook)
  189. (call-interactively #'ein:worksheet-insert-cell-below)
  190. (let ((pager-name (ein:$notebook-pager ein:%notebook%)))
  191. (ein:aif (get-buffer pager-name)
  192. (kill-buffer it))
  193. (insert "file")
  194. (call-interactively #'ein:pytools-request-help)
  195. ;; Pager buffer will be created when got the response
  196. (ein:testing-wait-until (lambda () (get-buffer pager-name)))
  197. (with-current-buffer (get-buffer pager-name)
  198. (should (search-forward "Docstring:\nfile")))))))