emacs-ipython-notebook/tests/test-ein-notebook.el
2012-05-18 02:59:00 +02:00

338 lines
14 KiB
EmacsLisp
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(eval-when-compile (require 'cl))
(require 'ert)
(when load-file-name
(add-to-list 'load-path
(concat (file-name-directory load-file-name) "mocker")))
(require 'mocker)
(require 'ein-notebook)
(defvar eintest:notebook-data-simple-json
"{
\"metadata\": {
\"name\": \"Untitled0\"
},
\"name\": \"Untitled0\",
\"nbformat\": 2,
\"worksheets\": [
{
\"cells\": [
{
\"cell_type\": \"code\",
\"collapsed\": false,
\"input\": \"1 + 1\",
\"language\": \"python\",
\"outputs\": [
{
\"output_type\": \"pyout\",
\"prompt_number\": 1,
\"text\": \"2\"
}
],
\"prompt_number\": 1
}
]
}
]
}
")
(defun eintest:notebook-from-json (json-string &optional notebook-id)
(unless notebook-id (setq notebook-id "NOTEBOOK-ID"))
(with-temp-buffer
(erase-buffer)
(insert json-string)
(flet ((pop-to-buffer (buf) buf)
(ein:notebook-start-kernel ()))
(ein:notebook-url-retrieve-callback
nil
(ein:notebook-new "DUMMY-URL" notebook-id)))))
(defun eintest:notebook-make-data (cells &optional name)
(unless name (setq name "Dummy Name"))
`((metadata . ((name . ,name)))
(name . ,name)
(worksheets . [((cells . ,(apply #'vector cells)))])))
(defun eintest:notebook-make-empty (&optional name)
"Make empty notebook and return its buffer."
(eintest:notebook-from-json
(json-encode (eintest:notebook-make-data nil name))))
(ert-deftest ein:notebook-from-json-simple ()
(with-current-buffer (eintest:notebook-from-json
eintest:notebook-data-simple-json)
(should (ein:$notebook-p ein:notebook))
(should (equal (ein:$notebook-notebook-id ein:notebook) "NOTEBOOK-ID"))
(should (equal (ein:$notebook-notebook-name ein:notebook) "Untitled0"))
(should (equal (ein:notebook-ncells ein:notebook) 1))
(let ((cell (car (ein:notebook-get-cells ein:notebook))))
(should (ein:codecell-p cell))
(should (equal (oref cell :input) "1 + 1"))
(should (equal (oref cell :input-prompt-number) 1))
(let ((outputs (oref cell :outputs)))
(should (equal (length outputs) 1))
(let ((o1 (car outputs)))
(should (equal (plist-get o1 :output_type) "pyout"))
(should (equal (plist-get o1 :prompt_number) 1))
(should (equal (plist-get o1 :text) "2")))))))
(ert-deftest ein:notebook-from-json-empty ()
(with-current-buffer (eintest:notebook-make-empty)
(should (ein:$notebook-p ein:notebook))
(should (equal (ein:$notebook-notebook-id ein:notebook) "NOTEBOOK-ID"))
(should (equal (ein:$notebook-notebook-name ein:notebook) "Dummy Name"))
(should (equal (ein:notebook-ncells ein:notebook) 0))))
(ert-deftest ein:notebook-insert-cell-below-command-simple ()
(with-current-buffer (eintest:notebook-make-empty)
(ein:notebook-insert-cell-below-command)
(ein:notebook-insert-cell-below-command)
(ein:notebook-insert-cell-below-command)
(should (equal (ein:notebook-ncells ein:notebook) 3))))
(ert-deftest ein:notebook-insert-cell-above-command-simple ()
(with-current-buffer (eintest:notebook-make-empty)
(ein:notebook-insert-cell-above-command)
(ein:notebook-insert-cell-above-command)
(ein:notebook-insert-cell-above-command)
(should (equal (ein:notebook-ncells ein:notebook) 3))))
(ert-deftest ein:notebook-delete-cell-command-simple ()
(with-current-buffer (eintest:notebook-make-empty)
(loop repeat 3
do (ein:notebook-insert-cell-above-command))
(should (equal (ein:notebook-ncells ein:notebook) 3))
(loop repeat 3
do (ein:notebook-delete-cell-command))
(should (equal (ein:notebook-ncells ein:notebook) 0))))
(ert-deftest ein:notebook-kill-cell-command-simple ()
(with-current-buffer (eintest:notebook-make-empty)
(let (ein:kill-ring ein:kill-ring-yank-pointer)
(loop repeat 3
do (ein:notebook-insert-cell-above-command))
(should (equal (ein:notebook-ncells ein:notebook) 3))
(loop for i from 1 to 3
do (ein:notebook-kill-cell-command)
do (should (equal (length ein:kill-ring) i))
do (should (equal (ein:notebook-ncells ein:notebook) (- 3 i)))))))
(ert-deftest ein:notebook-copy-cell-command-simple ()
(with-current-buffer (eintest:notebook-make-empty)
(let (ein:kill-ring ein:kill-ring-yank-pointer)
(loop repeat 3
do (ein:notebook-insert-cell-above-command))
(should (equal (ein:notebook-ncells ein:notebook) 3))
(loop repeat 3
do (ein:notebook-copy-cell-command))
(should (equal (ein:notebook-ncells ein:notebook) 3))
(should (equal (length ein:kill-ring) 3)))))
(ert-deftest ein:notebook-yank-cell-command-simple ()
(with-current-buffer (eintest:notebook-make-empty)
(let (ein:kill-ring ein:kill-ring-yank-pointer)
(loop repeat 3
do (ein:notebook-insert-cell-above-command))
(should (equal (ein:notebook-ncells ein:notebook) 3))
(loop repeat 3
do (ein:notebook-kill-cell-command))
(should (equal (ein:notebook-ncells ein:notebook) 0))
(should (equal (length ein:kill-ring) 3))
(loop repeat 3
do (ein:notebook-yank-cell-command))
(should (equal (ein:notebook-ncells ein:notebook) 3)))))
(ert-deftest ein:notebook-yank-cell-command-two-buffers ()
(let (ein:kill-ring ein:kill-ring-yank-pointer)
(with-current-buffer (eintest:notebook-make-empty "NB1")
(ein:notebook-insert-cell-above-command)
(should (equal (ein:notebook-ncells ein:notebook) 1))
(ein:notebook-kill-cell-command)
(should (equal (ein:notebook-ncells ein:notebook) 0))
(flet ((y-or-n-p (&rest ignore) t))
;; FIXME: are there anyway to skip confirmation?
(kill-buffer)))
(with-current-buffer (eintest:notebook-make-empty "NB2")
(ein:notebook-yank-cell-command)
(should (equal (ein:notebook-ncells ein:notebook) 1)))))
(ert-deftest ein:notebook-toggle-cell-type-simple ()
(with-current-buffer (eintest:notebook-make-empty)
(ein:notebook-insert-cell-above-command)
(insert "some text")
(should (ein:codecell-p (ein:notebook-get-current-cell)))
;; toggle to markdown
(ein:notebook-toggle-cell-type)
(should (ein:markdowncell-p (ein:notebook-get-current-cell)))
(should (looking-at "some text"))
;; toggle to code
(ein:notebook-toggle-cell-type)
(should (ein:codecell-p (ein:notebook-get-current-cell)))
(should (looking-at "some text"))))
(ert-deftest ein:notebook-split-cell-at-point-simple ()
(with-current-buffer (eintest:notebook-make-empty)
(ein:notebook-insert-cell-above-command)
(insert "some\ntext")
(search-backward "text")
;; do it
(ein:notebook-split-cell-at-point)
;; check the "tail" cell
(let ((cell (ein:notebook-get-current-cell)))
(ein:cell-goto cell)
(should (equal (ein:cell-get-text cell) "text")))
;; check the "head" cell
(ein:notebook-goto-prev-input-command)
(let ((cell (ein:notebook-get-current-cell)))
(ein:cell-goto cell)
(should (equal (ein:cell-get-text cell) "some\n")))))
(ert-deftest ein:notebook-goto-next-input-command-simple ()
(with-current-buffer (eintest:notebook-make-empty)
(loop for i downfrom 2 to 0
do (ein:notebook-insert-cell-above-command)
do (insert (format "Cell %s" i)))
(should (equal (ein:notebook-ncells ein:notebook) 3))
;; (message "%s" (buffer-string))
(loop for i from 0 below 2
do (beginning-of-line) ; This is required, I need to check why
do (should (looking-at (format "Cell %s" i)))
do (ein:notebook-goto-next-input-command)
do (should (looking-at (format "Cell %s" (1+ i)))))))
(ert-deftest ein:notebook-goto-prev-input-command-simple ()
(with-current-buffer (eintest:notebook-make-empty)
(loop for i from 0 below 3
do (ein:notebook-insert-cell-below-command)
do (insert (format "Cell %s" i)))
(should (equal (ein:notebook-ncells ein:notebook) 3))
;; (message "%s" (buffer-string))
(loop for i downfrom 2 to 1
do (beginning-of-line) ; This is required, I need to check why
do (should (looking-at (format "Cell %s" i)))
do (ein:notebook-goto-prev-input-command)
do (should (looking-at (format "Cell %s" (1- i)))))))
(ert-deftest ein:notebook-move-cell-up-command-simple ()
(with-current-buffer (eintest:notebook-make-empty)
(loop for i from 0 below 3
do (ein:notebook-insert-cell-below-command)
do (insert (format "Cell %s" i)))
(beginning-of-line)
(should (looking-at "Cell 2"))
(loop repeat 2
do (ein:notebook-move-cell-up-command))
;; (message "%s" (buffer-string))
(beginning-of-line)
(should (looking-at "Cell 2"))
(should (search-forward "Cell 0" nil t))
(should (search-forward "Cell 1" nil t))
(should-not (search-forward "Cell 2" nil t))))
(ert-deftest ein:notebook-move-cell-down-command-simple ()
(with-current-buffer (eintest:notebook-make-empty)
(loop for i from 0 below 3
do (ein:notebook-insert-cell-above-command)
do (insert (format "Cell %s" i)))
(loop repeat 2
do (ein:notebook-move-cell-down-command))
(beginning-of-line)
(should (looking-at "Cell 2"))
(should (search-backward "Cell 0" nil t))
(should (search-backward "Cell 1" nil t))
(should-not (search-backward "Cell 2" nil t))))
(ert-deftest ein:notebook-execute-current-cell ()
(with-current-buffer (eintest:notebook-make-empty)
(ein:notebook-insert-cell-below-command)
(let ((text "print 'Hello World'")
(cell (ein:notebook-get-current-cell))
(msg-id "DUMMY-MSG-ID"))
(setf (ein:$notebook-kernel ein:notebook) "DUMMY-KERNEL")
(insert text)
(mocker-let ((ein:kernel-execute
(notebook text)
((:input (list (ein:$notebook-kernel ein:notebook) text)
:output msg-id)))
(ein:kernel-ready-p
(kernel)
((:input (list (ein:$notebook-kernel ein:notebook))
:output t))))
(ein:notebook-execute-current-cell))
(should (equal (gethash msg-id
(ein:$notebook-msg-cell-map ein:notebook))
(oref cell :cell-id)))
(save-excursion
(goto-char (point-min))
(should-not (search-forward "In [1]:" nil t)))
(let* ((payload nil)
(content (list :execution_count 1 :payload payload))
(packet (list :msg_type "execute_reply"
:parent_header (list :msg_id msg-id)
:content content)))
(ein:notebook-handle-shell-reply ein:notebook (json-encode packet)))
(should (= (oref cell :input-prompt-number) 1))
(save-excursion
(goto-char (point-min))
(should (search-forward "In [1]:" nil t)))
(let* ((content (list :data "'Hello World'"
:name "stdout"))
(packet (list :msg_type "stream"
:parent_header (list :msg_id msg-id)
:content content)))
(ein:notebook-handle-iopub-reply ein:notebook (json-encode packet)))
(should (= (ein:cell-num-outputs cell) 1))
(save-excursion
(goto-char (point-min))
(should (search-forward "In [1]:" nil t))
(should (search-forward "print 'Hello World'" nil t))
(should (search-forward "Hello World" nil t)) ; stream output
(should-not (search-forward "Hello World" nil t))))))
;; Misc unit tests
(ert-deftest ein:notebook-test-notebook-name-simple ()
(should-not (ein:notebook-test-notebook-name nil))
(should-not (ein:notebook-test-notebook-name ""))
(should-not (ein:notebook-test-notebook-name "/"))
(should-not (ein:notebook-test-notebook-name "\\"))
(should-not (ein:notebook-test-notebook-name "a/b"))
(should-not (ein:notebook-test-notebook-name "a\\b"))
(should (ein:notebook-test-notebook-name "This is a OK notebook name")))
(ert-deftest ein:notebook-console-security-dir-string ()
(let ((ein:notebook-console-security-dir "/some/dir/")
(notebook (ein:notebook-new "DUMMY-URL-OR-PORT" "DUMMY-NOTEBOOK-ID")))
(should (equal (ein:notebook-console-security-dir-get notebook)
ein:notebook-console-security-dir))))
(ert-deftest ein:notebook-console-security-dir-list ()
(let ((ein:notebook-console-security-dir
'((8888 . "/dir/8888/")
("htttp://dummy.org" . "/dir/http/")
(7777 . my-secret-directory)
(default . "/dir/default/")))
(my-secret-directory "/dir/secret/"))
(let ((notebook (ein:notebook-new 8888 "DUMMY-NOTEBOOK-ID")))
(should (equal (ein:notebook-console-security-dir-get notebook)
"/dir/8888/")))
(let ((notebook (ein:notebook-new "htttp://dummy.org" "DUMMY-NOTEBOOK-ID")))
(should (equal (ein:notebook-console-security-dir-get notebook)
"/dir/http/")))
(let ((notebook (ein:notebook-new 7777 "DUMMY-NOTEBOOK-ID")))
(should (equal (ein:notebook-console-security-dir-get notebook)
"/dir/secret/")))
(let ((notebook (ein:notebook-new 9999 "DUMMY-NOTEBOOK-ID")))
(should (equal (ein:notebook-console-security-dir-get notebook)
"/dir/default/")))))
(ert-deftest ein:notebook-console-security-dir-func ()
(let ((ein:notebook-console-security-dir
'(lambda (x) (should (equal x "DUMMY-URL-OR-PORT")) "/dir/"))
(notebook (ein:notebook-new "DUMMY-URL-OR-PORT" "DUMMY-NOTEBOOK-ID")))
(should (equal (ein:notebook-console-security-dir-get notebook) "/dir/"))))