Created
November 17, 2013 20:46
-
-
Save dbushenko/7518070 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defun string/starts-with (s arg) | |
(cond ((>= (length s) (length arg)) | |
(string-equal (substring s 0 (length arg)) arg)) | |
(t nil))) | |
(defun chomp (str) | |
(while (string-match "\\`\n+\\|^\\s-+\\|\\s-+$\\|\n+\\'" | |
str) | |
(setq str (replace-match "" t t str))) | |
str) | |
;; Scan comments from the current point to the top while it finds | |
;; lines beginning with ';;#'. | |
;; Each line with ';;#' -- testcase. Remove the ';;#', split it and | |
;; save as a list with two values. | |
;; Results are accumulated in the variable 'tc'. | |
(defun get-test-cases (tc) | |
;; 1) Mark whole current line from the beginning to the end. | |
(beginning-of-line) | |
(set-mark (point)) | |
(end-of-line) | |
;; 2) Copy current line text (without text properties). | |
(let ((line (buffer-substring-no-properties (mark) (point)))) | |
;; 3) If the line starts with ';;#' -- it is a testcase, process it. | |
(if (string/starts-with line ";;#") | |
;; 3a) Get the input and output data from the testcase. | |
(let* ((splitted (split-string line "->")) | |
(fst (car splitted)) | |
(snd (cadr splitted)) | |
(data (list (chomp (substring fst 3 (length fst))) | |
(chomp snd)))) | |
;; 3b) Set cursor to the line above. | |
(previous-line) | |
;; 3c) Continue searching for testcases. | |
(get-test-cases (cons data tc))) | |
;; 4) When no more testcases found -- return the accumulated results. | |
tc))) | |
(defun tst-begin (func-name) | |
(concat ";;vvv " func-name)) | |
(defun tst-end (func-name) | |
(concat ";;^^^ " func-name)) | |
;; The function finds autogenerated testcase and deletes it. | |
(defun delete-tests-from-buffer (func-name file-name) | |
;; 1) Open tests file. | |
(with-current-buffer (find-file tst-file) | |
;; 2) Find test for the specified function. | |
(if (search-forward (tst-begin func-name) (point-max) 't) | |
;; 3) If the test was found -- find its end and delete the test. | |
(progn | |
(previous-line) | |
(beginning-of-line) | |
(set-mark (point)) | |
(search-forward (tst-end func-name)) | |
(next-line) | |
(kill-region (mark) (point)))))) | |
;; The function generates test for the specified function | |
(defun add-tests-to-buffer (func-name filename testcases) | |
;; 1) Open tests file. | |
(with-current-buffer (find-file tst-file) | |
;; 2) Writ test beginning to the end of the file. | |
(end-of-buffer) | |
(newline) | |
(insert (tst-begin func-name)) | |
(newline) | |
(insert (concat "(deftest " func-name "-test\n(testing \"Autotest of " func-name "\"")) | |
;; 3) For each testcase add some code to the test function. | |
(dolist (tst testcases) | |
(newline) | |
(insert "(is (= ("func-name " " (car tst) ") " (cadr tst) "))" )) | |
;; 4) Insert ending of the test function. | |
(insert "))\n") | |
(insert (tst-end func-name)) | |
(indent-region 1 (point-max)))) | |
;; Command which generates tests. | |
(defun generate-test-case () | |
(interactive) | |
(let* ((func-name (read-string "Function: " (thing-at-point 'symbol))) ;; ask function name | |
(testcases nil) | |
(file-name (buffer-file-name)) ;; current file name | |
(root-dir (ede-lein2-project-root)) ;; project directory root | |
(src-file (substring file-name (+ 4 (length root-dir)) ;; exclude "src/" | |
(- (length file-name) 4))) ;; exclude ".clj" | |
(tst-file (concat root-dir "test/" src-file "_test.clj"))) | |
(save-excursion | |
;; 1) Go to the first comment line. | |
(previous-line) | |
;; 2) Search for testcases. | |
(setq testcases (get-test-cases nil)) | |
;; 3) Delete the test for the current function. | |
(delete-tests-from-buffer func-name file-name) | |
;; 4) Generate new test for the current function. | |
(add-tests-to-buffer func-name file-name testcases)))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment