Created
July 15, 2024 07:45
-
-
Save jnpn/311f538756e80be99c2835fe20183b06 to your computer and use it in GitHub Desktop.
Hackish code to run a test class or the test at point using transient (magit)
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
;;; django-extensions.el | |
;;; | |
;;; various helpers | |
;;; VARIABLES | |
;;; TOFIX change <project> | |
(defvar *project-dir* "/home/jnpn/Code/<project>") | |
;;; TOFIX: change <app> | |
(defvar *terminal-template* "xfce4-terminal --working-directory='%s' -H -T '[django.test %s]' -e 'docker compose -f docker-compose.test.yml exec -it <app> python manage.py test %s %s'") | |
;;; PYTHON | |
(defun pythonic-file-name () | |
"Return python qualified name for current file." | |
(->> (relative-file-name) | |
(s-replace "/" ".") | |
(s-replace ".py" ""))) | |
(defun get-class-context () | |
"Return the nearest top level class name for the line at point." | |
(save-excursion | |
(let* ((python-class-re "^class \\(.+\\)\\((.*)\\):") | |
;;; "^class \\\(\\\[^(\\\]+\\\):" | |
(match (re-search-backward python-class-re nil t))) | |
(message (if match (match-string 1) "not ok")) | |
(if match (match-string-no-properties 1) nil)))) | |
(defun get-def-context () | |
"Return the nearest def name for the line at point." | |
(save-excursion | |
(let* ((python-def-re " +def \\(.+\\)\\((.*)\\):") | |
(match (re-search-backward python-def-re nil t))) | |
(message (if match (match-string 1) "not ok")) | |
(if match (match-string-no-properties 1) nil)))) | |
(defun get-def-test-context () | |
"Return the nearest def name for the line at point." | |
(save-excursion | |
(let* ((python-def-re " +def \\(test_.+\\)\\((.*)\\):") | |
(match (re-search-backward python-def-re nil t))) | |
(message (if match (match-string 1) "not ok")) | |
(if match (match-string-no-properties 1) nil)))) | |
;;; DJANGO | |
(defun get-django-nose-fq-test-name () | |
"Compute the fully qualified test name at point. | |
<path>.<class>.<method>" | |
(interactive) | |
(if-let* ((ns (pythonic-file-name)) ;;(ns (-> (path-name) slash-to-dots)) | |
(class (get-class-context)) | |
(def (get-def-test-context)) | |
(fqtn (format "%s.%s.%s" ns class def))) | |
fqtn)) | |
(defun get-django-nose-fq-test-class-name () | |
"Compute the fully qualified test name at point. | |
<path>.<class>.<method>" | |
(interactive) | |
(if-let* ((ns (pythonic-file-name)) ;;(ns (-> (path-name) slash-to-dots)) | |
(class (get-class-context))) | |
(format "%s.%s" ns class))) | |
(defun copy-django-nose-fq-test-name (args) | |
"Copy fqtn to system clipboard." | |
(interactive "P") | |
(let ((fqtn (get-django-nose-fq-test-name))) | |
(progn | |
(message "[copied] %s" fqtn) | |
(gui-select-text fqtn)))) | |
(defun django-test-class-at-point (&optional options) | |
"Run the fqtn test at point." | |
; wip | |
(interactive) | |
(let ((hardcoded-root-dir *user-dir*) | |
(opt (mapconcat #'identity options " ")) | |
(tmpl *terminal-template*) | |
(fqtn (get-django-nose-fq-test-class-name))) | |
(message "[django-test] %s [opt] %s" fqtn opt) | |
(async-shell-command (format tmpl hardcoded-root-dir fqtn fqtn opt)))) | |
(defun django-test-at-point () | |
"Run the fqtn test at point." | |
(interactive) | |
(let ((hardcoded-root-dir *user-dir*) | |
(tmpl *terminal-template*) | |
(fqtn (get-django-nose-fq-test-name))) | |
(message "[django-test] %s" fqtn) | |
(async-shell-command (format tmpl hardcoded-root-dir fqtn fqtn)))) | |
;;; UI | |
;;; django test transient | |
;;; level ::= app | file | class | method @TODO | |
;;; args :: parallel . keep-db . failfast | |
(defun django-test-arguments () | |
(transient-args 'django-test-transient)) | |
(transient-define-suffix django-test-class-at-point-t (args) | |
"Dispatched for django-test-class-at-point." | |
;; :if #'magit-get-current-branch | |
;; :description #'magit-push--pushbranch-description | |
(interactive (list (django-test-arguments))) | |
(django-test-class-at-point args)) | |
(transient-define-prefix django-test-transient () | |
"Run django test." | |
[:description "Run django tests"] | |
["Arguments" | |
("-k" "Keep DB" "--keepdb") | |
("-f" "Fail Fast" "--failfast") | |
("-d" "Debug" "--pdb")] | |
["Test" | |
[("c" "class at point" django-test-class-at-point-t) | |
("t" "test at point" | |
(lambda () | |
(interactive) | |
(django-test-at-point)))] | |
]) | |
(provide 'django-extension) | |
;;; SAMPLES TEST | |
" | |
class TestEmacs(TestCase): | |
def test_1(self): | |
print('1') | |
def test_2(self): | |
print('2') | |
" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment