-
Notifications
You must be signed in to change notification settings - Fork 3
/
test.el
198 lines (169 loc) · 7.31 KB
/
test.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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
;; This file is part of the parinfer-elisp project:
;; https://github.com/oakmac/parinfer-elisp
;;
;; You can run this file on the command line:
;; emacs --script test.el
;;
;; It will run the Parinfer test suite and output the results to the console.
;; The script will exit with "1" on any test failure. Exit "0" otherwise.
(require 'json)
(add-to-list 'load-path (expand-file-name "."))
(load "parinferlib")
;; NOTE: useful when debugging a failed test
;; (setq debug-on-error t)
;;------------------------------------------------------------------------------
;; Util functions
;;------------------------------------------------------------------------------
(defun get-string-from-file (file-path)
"Return file-path's file content."
(with-temp-buffer
(insert-file-contents file-path)
(buffer-string)))
(defun print-err (msg)
(message msg))
(defun println (txt)
(princ (concat txt "\n")))
(defun squiggly-line ()
(println "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"))
(defun string-join (l)
(mapconcat 'identity l "\n"))
(defun convert-result-error (error)
"Converts error from the library result into a list."
(list (plist-get error :name)
(plist-get error :line-no)
(plist-get error :x)))
(defun convert-test-error (error)
"Converts error from the test JSON into a list."
(list (plist-get error :name)
(plist-get error :lineNo)
(plist-get error :x)))
(defun convert-result-tabstops (tabstops)
"Converts tabStops from the library result into a list."
(mapcar
(lambda (ts) (list (plist-get ts :ch)
(plist-get ts :line-no)
(plist-get ts :x)))
tabstops))
(defun convert-test-tabstops (tabstops)
"Converts tabStops from the test JSON into a list."
(mapcar
(lambda (ts) (list (plist-get ts :ch)
(plist-get ts :lineNo)
(plist-get ts :x)))
tabstops))
;;------------------------------------------------------------------------------
;; Load test files
;;------------------------------------------------------------------------------
(defconst indent-mode-tests
(let ((test-str (get-string-from-file "tests/indent-mode.json"))
(json-object-type 'plist))
(json-read-from-string test-str)))
(defconst paren-mode-tests
(let ((test-str (get-string-from-file "tests/paren-mode.json"))
(json-object-type 'plist))
(json-read-from-string test-str)))
;;------------------------------------------------------------------------------
;; Test runner
;;------------------------------------------------------------------------------
(defvar num-tests-failed 0)
(defvar num-tests-ran 0)
(defun run-test (mode test)
(let* ((mode-string (if (equal :indent mode) "Indent Mode" "Paren Mode"))
(in (plist-get test :in))
(out (plist-get test :out))
(out-cursor (plist-get out :cursor))
(out-error (plist-get out :error))
(out-tabstops (plist-get out :tabStops))
(test-id (number-to-string (plist-get in :fileLineNo)))
(in-text (string-join (plist-get in :lines)))
(expected-text (string-join (plist-get out :lines)))
(in-cursor (plist-get in :cursor))
(cursor-x (plist-get in-cursor :cursorX))
(cursor-line (plist-get in-cursor :cursorLine))
(cursor-dx (plist-get in-cursor :cursorDx))
(preview-cursor-scope (plist-get in-cursor :previewCursorScope))
(options (list :cursor-x cursor-x
:cursor-line cursor-line
:cursor-dx cursor-dx
:preview-cursor-scope preview-cursor-scope))
(test-idempotence? (and (not out-error)
(not out-tabstops)
(not cursor-dx)))
(test-cross-mode? (and (not out-error)
(not out-tabstops)
(not in-cursor)))
(result-1 (if (equal :indent mode)
(parinferlib-indent-mode in-text options)
(parinferlib-paren-mode in-text options)))
(out-text-1 (plist-get result-1 :text))
(result-2 (if (equal :indent mode)
(parinferlib-indent-mode out-text-1 options)
(parinferlib-paren-mode out-text-1 options)))
(out-text-2 (plist-get result-2 :text))
(failed? nil))
;; in/out text equality
(when (not (equal out-text-1 expected-text))
(setq failed? t)
(print-err (concat mode-string " In/Out Text failure: test id " test-id)))
;; check cursor-x
(when (and in-cursor
(not (equal (plist-get result-1 :cursor-x)
(plist-get out-cursor :cursorX))))
(setq failed? t)
(print-err (concat mode-string " cursorX failure: test id " test-id)))
;; check error output
(when out-error
(let ((result-error2 (convert-result-error (plist-get result-1 :error)))
(out-error2 (convert-test-error out-error)))
(when (or (plist-get result-1 :success)
(not (equal result-error2 out-error2)))
(setq failed? t)
(print-err (concat mode-string " Error Output failure: test id " test-id)))))
;; check tab stops
(when out-tabstops
(let ((result-tabstops (convert-result-tabstops (plist-get result-1 :tab-stops)))
(out-tabstops2 (convert-test-tabstops out-tabstops)))
(when (not (equal result-tabstops out-tabstops2))
(setq failed? t)
(print-err (concat mode-string " Tab Stops failure: test id " test-id)))))
;; idempotence
(when test-idempotence?
(when (not (equal out-text-2 expected-text))
(setq failed? t)
(print-err (concat mode-string " Idempotence failure: test id " test-id))))
;; cross-mode preservation
(when test-cross-mode?
(let* ((result-3 (if (equal :indent mode)
(parinferlib-paren-mode out-text-1 options)
(parinferlib-indent-mode out-text-1 options)))
(out-text-3 (plist-get result-3 :text)))
(when (not (equal out-text-3 expected-text))
(setq failed? t)
(print-err (concat mode-string " Cross-mode Preservation failure: test id " test-id)))))
;; increment the test counts
(setq num-tests-ran (1+ num-tests-ran))
(when failed?
(setq num-tests-failed (1+ num-tests-failed)))))
;;------------------------------------------------------------------------------
;; Run the tests and print the result
;;------------------------------------------------------------------------------
(princ "\n\n")
(squiggly-line)
(println "Running Parinfer Tests...")
(defvar start-time (current-time))
(squiggly-line)
(mapc (lambda (test) (run-test :indent test)) indent-mode-tests)
(mapc (lambda (test) (run-test :paren test)) paren-mode-tests)
(squiggly-line)
(let ((done-msg (if (equal 0 num-tests-failed) "SUCCESS! " "Done. ")))
(println (concat done-msg
"Ran " (number-to-string num-tests-ran) " tests. "
(number-to-string num-tests-failed) " failures.")))
(println
(format "Took %s seconds." (float-time (time-subtract (current-time) start-time))))
(squiggly-line)
(princ "\n\n")
;; exit with "1" on failure
;; NOTE: this is necessary for travis-ci
(when (not (equal num-tests-failed 0))
(kill-emacs 1))