-
Notifications
You must be signed in to change notification settings - Fork 0
/
rename_tests.el
166 lines (138 loc) · 6.09 KB
/
rename_tests.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
;;; rename_tests.el --- Standardize test names in a project
;;
;;; Code:
(defvar dir "/home/dan/projects/clojure/cider-nrepl")
(defvar clojure-files (directory-files-recursively dir ".clj$"))
(defvar deftest-regexp "^\\s-*(deftest\\s-+")
;;; Commentary:
;; In CIDER-repl, (the java side), test names had gotten unwiedly and
;; no longer conformed to any particular style. This ran over all
;; files looking for test names and checked to see if they conformed,
;; and if not, if they could be easily fixed.
(require 'cl-seq)
(defun valid-test-name-p (test-name)
"Test name ends with \"-test\"."
(and (not (string-blank-p test-name))
(string-suffix-p "-test" test-name)))
(defun pluralized-test-p (test-name)
(string-suffix-p "tests" test-name))
(defun prefixed-with-test-p (test-name)
(string-prefix-p "test-" test-name))
(defun lacks-test-p (test-name)
(not (string-match "test" test-name)))
;; rename to classify
(defun analyze-test-names (name)
(cond ((valid-test-name-p name) `(,name valid))
((pluralized-test-p name) `(,name pluralized))
((prefixed-with-test-p name) `(,name prefixed))
((lacks-test-p name) `(,name missing-suffix))
(t `(,name unrecognized))))
(defun fix-testname (name reason)
(cond ((eq reason 'missing-suffix)
(format "%s-test" name))
((eq reason 'prefixed)
(fix-testname (replace-regexp-in-string "test-" "" name)
'missing-suffix))
((eq reason 'pluralized)
(substring name 0 (- (length name) 1)))))
(defun deftest-regexp-for (name)
(concat deftest-regexp (escape-name name)))
(defun appears-once-and-only-once-p (name)
(let ((occurences 0)
(regexp (deftest-regexp-for name)))
(goto-char (point-min))
(while (re-search-forward regexp nil t)
(incf occurences))
(= 1 occurences)))
;; data access
;; building up data like (filename ((testname classification) ...))
(defun names-and-states (result)
(cadr result))
(defun testname-of (name-and-state)
(car name-and-state))
(defun state-of (name-and-state)
(cadr name-and-state))
(defun filename-of (result)
(car result))
(defun can-fix (reason)
"Determine if REASON can be programatically fixed where REASON
is one of unrecognized, pluralized, prefixed, missing-suffix"
(member reason '(missing-suffix prefixed pluralized)))
(defun escape-name (name)
"Annoyingly, one test NAME had a question mark in it, which
must be made a literal question mark in the regex rather than an
optional specifier."
(replace-regexp-in-string "?" "\\?" name))
(defun make-new-testname! (testpair)
"Assumes it is inside of a buffer. be careful. TESTPAIR is a
list of testname and classification like (\"data-test\" valid) or
some other combination. We remember the old name, determine the
new name, make sure that we can correctly locate it, the replace
it."
(let ((old-name (testname-of testpair))
(reason (state-of testpair)))
(when (and (can-fix reason)
(appears-once-and-only-once-p old-name))
(let ((new-name (fix-testname old-name reason))
(regexp (deftest-regexp-for old-name)))
(goto-char (point-min))
(re-search-forward regexp nil t 1)
(beginning-of-line)
(re-search-forward (escape-name old-name) nil t)
(replace-match new-name)))))
(defun get-test-names (file)
"Walk though a FILE looking for deftest forms. This grabs the
text after deftest until the end of the line. Could definitely be better"
(let ((test-names))
(with-temp-buffer
(insert-file-contents file)
(goto-char (point-min))
(while (re-search-forward deftest-regexp nil t)
(push (buffer-substring-no-properties (point) (progn (move-end-of-line 1) (point)))
test-names)))
test-names))
(defun process-test-names-for-file (file)
"Create the data structure of a list of filename with a list of
test names and analysis."
(let ((testnames (get-test-names file)))
(when testnames
(list file (mapcar #'analyze-test-names testnames)))))
(defun fixup-tests-for (files)
(let ((test-infos (remove-if #'null (mapcar #'process-test-names-for-file files))))
(mapc #'(lambda (test-info)
(with-current-buffer (find-file (filename-of test-info))
(mapc #'make-new-testname! (names-and-states test-info))
(save-buffer)))
test-infos)))
(defun mapcon (f l)
(apply #'append (mapcar f l)))
;; filter the lists of the data to just the interesting classifications
;; (remove-if #'(lambda (l) (not (names-and-states l)))
;; (mapcar #'(lambda (test-info)
;; (list (filename-of test-info)
;; (remove-if-not #'(lambda (testpair)
;; (eq 'prefixed (state-of testpair)))
;; (names-and-states test-info))))
;; (remove-if #'null (mapcar #'process-test-names-for-file clojure-files))))
(let ((valid 0)
(pluralized 0)
(prefixed 0)
(missing-suffix 0)
(unrecognized 0))
(mapc #'(lambda (tests)
(mapc #'(lambda (result)
(pcase (cadr result)
('valid (incf valid))
('pluralized (incf pluralized))
('prefixed (incf prefixed))
('missing-suffix (incf missing-suffix))
('unrecognized (incf unrecognized))))
(cadr tests)))
(remove-if #'null (mapcar #'process-test-names-for-file clojure-files)))
(format "valid: %s, pluralized: %s, prefixed: %s, missing-suffix: %s, unrecognized: %s" valid pluralized prefixed missing-suffix unrecognized))
;; (fixup-tests-for '("/home/dan/projects/clojure/cider-nrepl/test/clj/cider/nrepl/middleware/util/instrument_test.clj"))
;; (remove-if #'null (mapcar #'process-test-names-for-file clojure-files))
;;(fixup-tests-for clojure-files)
;; (fixup-tests-for '("/home/dan/projects/clojure/cider-nrepl/test/clj/cider/nrepl/middleware/util/instrument_test.clj"))
(provide 'rename_tests)
;;; rename_tests.el ends here