~ubuntu-branches/ubuntu/trusty/erlang/trusty

« back to all changes in this revision

Viewing changes to lib/tools/emacs/erlang-eunit.el

  • Committer: Bazaar Package Importer
  • Author(s): Clint Byrum
  • Date: 2011-05-05 15:48:43 UTC
  • mfrom: (3.5.13 sid)
  • Revision ID: james.westby@ubuntu.com-20110505154843-0om6ekzg6m7ugj27
Tags: 1:14.b.2-dfsg-3ubuntu1
* Merge from debian unstable.  Remaining changes:
  - Drop libwxgtk2.8-dev build dependency. Wx isn't in main, and not
    supposed to.
  - Drop erlang-wx binary.
  - Drop erlang-wx dependency from -megaco, -common-test, and -reltool, they
    do not really need wx. Also drop it from -debugger; the GUI needs wx,
    but it apparently has CLI bits as well, and is also needed by -megaco,
    so let's keep the package for now.
  - debian/patches/series: Do what I meant, and enable build-options.patch
    instead.
* Additional changes:
  - Drop erlang-wx from -et
* Dropped Changes:
  - patches/pcre-crash.patch: CVE-2008-2371: outer level option with
    alternatives caused crash. (Applied Upstream)
  - fix for ssl certificate verification in newSSL: 
    ssl_cacertfile_fix.patch (Applied Upstream)
  - debian/patches/series: Enable native.patch again, to get stripped beam
    files and reduce the package size again. (build-options is what
    actually accomplished this)
  - Remove build-options.patch on advice from upstream and because it caused
    odd build failures.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
;;
2
2
;; %CopyrightBegin%
3
 
;; 
4
 
;; Copyright Ericsson AB 2009. All Rights Reserved.
5
 
;; 
 
3
;;
 
4
;; Copyright Ericsson AB 2009-2010. All Rights Reserved.
 
5
;;
6
6
;; The contents of this file are subject to the Erlang Public License,
7
7
;; Version 1.1, (the "License"); you may not use this file except in
8
8
;; compliance with the License. You should have received a copy of the
9
9
;; Erlang Public License along with this software. If not, it can be
10
10
;; retrieved online at http://www.erlang.org/.
11
 
;; 
 
11
;;
12
12
;; Software distributed under the License is distributed on an "AS IS"
13
13
;; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
14
;; the License for the specific language governing rights and limitations
15
15
;; under the License.
16
 
;; 
 
16
;;
17
17
;; %CopyrightEnd%
18
18
;;;
19
19
;;; Purpose: Provide EUnit utilities.
20
20
;;;
21
21
;;; Author: Klas Johansson
22
22
 
23
 
(defvar erlang-eunit-separate-src-and-test-directories t
24
 
  "*Whether or not to keep source and EUnit test files in separate directories")
 
23
(eval-when-compile
 
24
  (require 'cl))
 
25
 
 
26
(defvar erlang-eunit-src-candidate-dirs '("../src" ".")
 
27
  "*Name of directories which to search for source files matching
 
28
an EUnit test file.  The first directory in the list will be used,
 
29
if there is no match.")
 
30
 
 
31
(defvar erlang-eunit-test-candidate-dirs '("../test" ".")
 
32
  "*Name of directories which to search for EUnit test files matching
 
33
a source file.  The first directory in the list will be used,
 
34
if there is no match.")
 
35
 
 
36
(defvar erlang-eunit-autosave nil
 
37
  "*Set to non-nil to automtically save unsaved buffers before running tests.
 
38
This is useful, reducing the save-compile-load-test cycle to one keychord.")
 
39
 
 
40
(defvar erlang-eunit-recent-info '((mode . nil) (module . nil) (test . nil) (cover . nil))
 
41
  "Info about the most recent running of an EUnit test representation.")
25
42
 
26
43
;;;
27
44
;;; Switch between src/EUnit test buffers
41
58
  "Open the EUnit test file which corresponds to a src file"
42
59
  (find-file-other-window (erlang-eunit-test-filename src-file-path)))
43
60
 
44
 
 
45
61
;;;
46
62
;;; Open the src file which corresponds to the an EUnit test file
47
63
;;;
52
68
;;; Return the name and path of the EUnit test file
53
69
;;, (input may be either the source filename itself or the EUnit test filename)
54
70
(defun erlang-eunit-test-filename (file-path)
55
 
  (erlang-eunit-rewrite-filename file-path "test" "_tests"))
 
71
  (if (erlang-eunit-test-file-p file-path)
 
72
      file-path
 
73
    (erlang-eunit-rewrite-filename file-path erlang-eunit-test-candidate-dirs)))
56
74
 
57
75
;;; Return the name and path of the source file
58
76
;;, (input may be either the source filename itself or the EUnit test filename)
59
77
(defun erlang-eunit-src-filename (file-path)
60
 
  (erlang-eunit-rewrite-filename file-path "src" ""))
 
78
  (if (erlang-eunit-src-file-p file-path)
 
79
      file-path
 
80
    (erlang-eunit-rewrite-filename file-path erlang-eunit-src-candidate-dirs)))
61
81
 
62
82
;;; Rewrite a filename from the src or test filename to the other
63
 
(defun erlang-eunit-rewrite-filename (orig-file-path dest-dirname dest-suffix)
64
 
  (let* ((root-dir-name    (erlang-eunit-file-root-dir-name orig-file-path))
65
 
         (src-module-name  (erlang-eunit-source-module-name orig-file-path))
66
 
         (dest-base-name   (concat src-module-name dest-suffix ".erl"))
67
 
         (dest-dir-name-1  (file-name-directory orig-file-path))
68
 
         (dest-dir-name-2  (filename-join root-dir-name dest-dirname))
69
 
         (dest-file-name-1 (filename-join dest-dir-name-1 dest-base-name))
70
 
         (dest-file-name-2 (filename-join dest-dir-name-2 dest-base-name)))
71
 
    ;; This function tries to be a bit intelligent: 
72
 
    ;; * if there already is a test (or source) file in the same
73
 
    ;;   directory as a source (or test) file, it'll be picked
74
 
    ;; * if there already is a test (or source) file in a separate
75
 
    ;;   test (or src) directory, it'll be picked
76
 
    ;; * otherwise it'll resort to whatever alternative (same or
77
 
    ;;   separate directories) that the user has chosen
78
 
    (cond ((file-readable-p dest-file-name-1) 
79
 
           dest-file-name-1)
80
 
          ((file-readable-p dest-file-name-2) 
81
 
           dest-file-name-2)
82
 
          (erlang-eunit-separate-src-and-test-directories
83
 
           dest-file-name-2)
84
 
          (t
85
 
           dest-file-name-1))))
 
83
(defun erlang-eunit-rewrite-filename (orig-file-path candidate-dirs)
 
84
  (or (erlang-eunit-locate-buddy orig-file-path candidate-dirs)
 
85
      (erlang-eunit-buddy-file-path orig-file-path (car candidate-dirs))))
 
86
 
 
87
;;; Search for a file's buddy file (a source file's EUnit test file,
 
88
;;; or an EUnit test file's source file) in a list of candidate
 
89
;;; directories.
 
90
(defun erlang-eunit-locate-buddy (orig-file-path candidate-dirs)
 
91
  (when candidate-dirs
 
92
    (let ((buddy-file-path (erlang-eunit-buddy-file-path
 
93
                            orig-file-path
 
94
                            (car candidate-dirs))))
 
95
      (if (file-readable-p buddy-file-path)
 
96
          buddy-file-path
 
97
        (erlang-eunit-locate-buddy orig-file-path (cdr candidate-dirs))))))
 
98
 
 
99
(defun erlang-eunit-buddy-file-path (orig-file-path buddy-dir-name)
 
100
  (let* ((orig-dir-name   (file-name-directory orig-file-path))
 
101
         (buddy-dir-name  (file-truename
 
102
                           (filename-join orig-dir-name buddy-dir-name)))
 
103
         (buddy-base-name (erlang-eunit-buddy-basename orig-file-path)))
 
104
    (filename-join buddy-dir-name buddy-base-name)))
 
105
 
 
106
;;; Return the basename of the buddy file:
 
107
;;;     /tmp/foo/src/x.erl        --> x_tests.erl
 
108
;;;     /tmp/foo/test/x_tests.erl --> x.erl
 
109
(defun erlang-eunit-buddy-basename (file-path)
 
110
  (let ((src-module-name (erlang-eunit-source-module-name file-path)))
 
111
    (cond
 
112
     ((erlang-eunit-src-file-p file-path)
 
113
      (concat src-module-name "_tests.erl"))
 
114
     ((erlang-eunit-test-file-p file-path)
 
115
      (concat src-module-name ".erl")))))
 
116
 
 
117
;;; Checks whether a file is a source file or not
 
118
(defun erlang-eunit-src-file-p (file-path)
 
119
  (not (erlang-eunit-test-file-p file-path)))
86
120
 
87
121
;;; Checks whether a file is a EUnit test file or not
88
122
(defun erlang-eunit-test-file-p (file-path)
93
127
;;;     /tmp/foo/test/x_tests.erl --> x
94
128
(defun erlang-eunit-source-module-name (file-path)
95
129
  (interactive)
96
 
  (let* ((file-name (file-name-nondirectory file-path))
97
 
         (base-name (file-name-sans-extension file-name)))
98
 
    (if (string-match "^\\(.+\\)_tests$" base-name)
99
 
        (substring base-name (match-beginning 1) (match-end 1))
100
 
      base-name)))
101
 
 
102
 
;;; Return the directory name which is common to both src and test
103
 
;;;     /tmp/foo/src/x.erl        --> /tmp/foo
104
 
;;;     /tmp/foo/test/x_tests.erl --> /tmp/foo
105
 
(defun erlang-eunit-file-root-dir-name (file-path)
106
 
  (erlang-eunit-dir-parent-dirname (file-name-directory file-path)))
107
 
 
108
 
;;; Return the parent directory name of a directory
109
 
;;;     /tmp/foo/ --> /tmp
110
 
;;;     /tmp/foo  --> /tmp
111
 
(defun erlang-eunit-dir-parent-dirname (dir-name)
112
 
  (file-name-directory (directory-file-name dir-name)))
 
130
  (let ((module-name (erlang-eunit-module-name file-path)))
 
131
    (if (string-match "^\\(.+\\)_tests$" module-name)
 
132
        (substring module-name (match-beginning 1) (match-end 1))
 
133
      module-name)))
 
134
 
 
135
;;; Return the module name of the file
 
136
;;;     /tmp/foo/src/x.erl        --> x
 
137
;;;     /tmp/foo/test/x_tests.erl --> x_tests
 
138
(defun erlang-eunit-module-name (file-path)
 
139
  (interactive)
 
140
  (file-name-sans-extension (file-name-nondirectory file-path)))
113
141
 
114
142
;;; Older emacsen don't have string-match-p.
115
143
(defun erlang-eunit-string-match-p (regexp string &optional start)
125
153
      (concat dir file)
126
154
    (concat dir "/" file)))
127
155
 
 
156
;;; Get info about the most recent running of EUnit
 
157
(defun erlang-eunit-recent (key)
 
158
  (cdr (assq key erlang-eunit-recent-info)))
 
159
 
 
160
;;; Record info about the most recent running of EUnit
 
161
;;; Known modes are 'module-mode and 'test-mode
 
162
(defun erlang-eunit-record-recent (mode module test)
 
163
  (setcdr (assq 'mode erlang-eunit-recent-info) mode)
 
164
  (setcdr (assq 'module erlang-eunit-recent-info) module)
 
165
  (setcdr (assq 'test erlang-eunit-recent-info) test))
 
166
 
 
167
;;; Record whether the most recent running of EUnit included cover
 
168
;;; compilation
 
169
(defun erlang-eunit-record-recent-compile (under-cover)
 
170
  (setcdr (assq 'cover erlang-eunit-recent-info) under-cover))
 
171
 
 
172
;;; Determine options for EUnit.
 
173
(defun erlang-eunit-opts ()
 
174
  (if current-prefix-arg ", [verbose]" ""))
 
175
 
 
176
;;; Determine current test function
 
177
(defun erlang-eunit-current-test ()
 
178
  (save-excursion
 
179
    (erlang-end-of-function 1)
 
180
    (erlang-beginning-of-function 1)
 
181
    (erlang-name-of-function)))
 
182
 
 
183
(defun erlang-eunit-simple-test-p (test-name)
 
184
  (if (erlang-eunit-string-match-p "^\\(.+\\)_test$" test-name) t nil))
 
185
 
 
186
(defun erlang-eunit-test-generator-p (test-name)
 
187
  (if (erlang-eunit-string-match-p "^\\(.+\\)_test_$" test-name) t nil))
 
188
 
 
189
;;; Run one EUnit test
 
190
(defun erlang-eunit-run-test (module-name test-name)
 
191
  (let ((command
 
192
         (cond ((erlang-eunit-simple-test-p test-name)
 
193
                (format "eunit:test({%s, %s}%s)."
 
194
                        module-name test-name (erlang-eunit-opts)))
 
195
               ((erlang-eunit-test-generator-p test-name)
 
196
                (format "eunit:test({generator, %s, %s}%s)."
 
197
                        module-name test-name (erlang-eunit-opts)))
 
198
               (t (format "%% WARNING: '%s' is not a test function" test-name)))))
 
199
    (erlang-eunit-record-recent 'test-mode module-name test-name)
 
200
    (erlang-eunit-inferior-erlang-send-command command)))
 
201
 
128
202
;;; Run EUnit tests for the current module
129
 
(defun erlang-eunit-run-tests ()
130
 
  "Run the EUnit test suite for the current module.
131
 
 
132
 
With prefix arg, runs tests with the verbose flag set."
133
 
  (interactive)
134
 
  (let* ((module-name (erlang-add-quotes-if-needed
135
 
                       (erlang-eunit-source-module-name buffer-file-name)))
136
 
         (opts        (if current-prefix-arg ", [verbose]" ""))
137
 
         (command     (format "eunit:test(%s%s)." module-name opts)))
 
203
(defun erlang-eunit-run-module-tests (module-name)
 
204
  (let ((command (format "eunit:test(%s%s)." module-name (erlang-eunit-opts))))
 
205
    (erlang-eunit-record-recent 'module-mode module-name nil)
138
206
    (erlang-eunit-inferior-erlang-send-command command)))
139
207
 
 
208
(defun erlang-eunit-compile-and-run-recent ()
 
209
  "Compile the source and test files and repeat the most recent EUnit test run.
 
210
 
 
211
With prefix arg, compiles for debug and runs tests with the verbose flag set."
 
212
  (interactive)
 
213
  (case (erlang-eunit-recent 'mode)
 
214
    ('test-mode
 
215
     (erlang-eunit-compile-and-test
 
216
      'erlang-eunit-run-test (list (erlang-eunit-recent 'module)
 
217
                                   (erlang-eunit-recent 'test))))
 
218
    ('module-mode
 
219
     (erlang-eunit-compile-and-test
 
220
      'erlang-eunit-run-module-tests (list (erlang-eunit-recent 'module))
 
221
      (erlang-eunit-recent 'cover)))
 
222
    (t (error "EUnit has not yet been run.  Please run a test first."))))
 
223
 
 
224
(defun erlang-eunit-cover-compile ()
 
225
  "Cover compile current module."
 
226
  (interactive)
 
227
  (let* ((erlang-compile-extra-opts
 
228
          (append (list 'debug_info) erlang-compile-extra-opts))
 
229
         (module-name
 
230
          (erlang-add-quotes-if-needed
 
231
           (erlang-eunit-module-name buffer-file-name)))
 
232
         (compile-command
 
233
          (format "cover:compile_beam(%s)." module-name)))
 
234
    (erlang-compile)
 
235
    (if (erlang-eunit-last-compilation-successful-p)
 
236
        (erlang-eunit-inferior-erlang-send-command compile-command))))
 
237
 
 
238
(defun erlang-eunit-analyze-coverage ()
 
239
  "Analyze the data collected by cover tool for the module in the
 
240
current buffer.
 
241
 
 
242
Assumes that the module has been cover compiled prior to this
 
243
call.  This function will do two things: print the number of
 
244
covered and uncovered functions in the erlang shell and display a
 
245
new buffer called *<module name> coverage* which shows the source
 
246
code along with the coverage analysis results."
 
247
  (interactive)
 
248
  (let* ((module-name     (erlang-add-quotes-if-needed
 
249
                           (erlang-eunit-module-name buffer-file-name)))
 
250
         (tmp-filename    (make-temp-file "cover"))
 
251
         (analyze-command (format "cover:analyze_to_file(%s, \"%s\"). "
 
252
                                  module-name tmp-filename))
 
253
         (buf-name        (format "*%s coverage*" module-name)))
 
254
    (erlang-eunit-inferior-erlang-send-command analyze-command)
 
255
    ;; The purpose of the following snippet is to get the result of the
 
256
    ;; analysis from a file into a new buffer (or an old, if one with
 
257
    ;; the specified name already exists).  Also we want the erlang-mode
 
258
    ;; *and* view-mode to be enabled.
 
259
    (save-excursion
 
260
      (let ((buf (get-buffer-create (format "*%s coverage*" module-name))))
 
261
        (set-buffer buf)
 
262
        (setq buffer-read-only nil)
 
263
        (insert-file-contents tmp-filename nil nil nil t)
 
264
        (if (= (buffer-size) 0)
 
265
            (kill-buffer buf)
 
266
          ;; FIXME: this would be a good place to enable (emacs-mode)
 
267
          ;;        to get some nice syntax highlighting in the
 
268
          ;;        coverage report, but it doesn't play well with
 
269
          ;;        flymake.  Leave it off for now.
 
270
          (view-buffer buf))))
 
271
    (delete-file tmp-filename)))
 
272
 
 
273
(defun erlang-eunit-compile-and-run-current-test ()
 
274
  "Compile the source and test files and run the current EUnit test.
 
275
 
 
276
With prefix arg, compiles for debug and runs tests with the verbose flag set."
 
277
  (interactive)
 
278
  (let ((module-name (erlang-add-quotes-if-needed
 
279
                      (erlang-eunit-module-name buffer-file-name)))
 
280
        (test-name (erlang-eunit-current-test)))
 
281
    (erlang-eunit-compile-and-test
 
282
     'erlang-eunit-run-test (list module-name test-name))))
 
283
 
 
284
(defun erlang-eunit-compile-and-run-module-tests ()
 
285
  "Compile the source and test files and run all EUnit tests in the module.
 
286
 
 
287
With prefix arg, compiles for debug and runs tests with the verbose flag set."
 
288
  (interactive)
 
289
  (let ((module-name (erlang-add-quotes-if-needed
 
290
                      (erlang-eunit-source-module-name buffer-file-name))))
 
291
    (erlang-eunit-compile-and-test
 
292
     'erlang-eunit-run-module-tests (list module-name))))
 
293
 
140
294
;;; Compile source and EUnit test file and finally run EUnit tests for
141
295
;;; the current module
142
 
(defun erlang-eunit-compile-and-run-tests ()
143
 
  "Compile the source and test files and run the EUnit test suite.
 
296
(defun erlang-eunit-compile-and-test (test-fun test-args &optional under-cover)
 
297
   "Compile the source and test files and run the EUnit test suite.
144
298
 
 
299
If under-cover is set to t, the module under test is compile for
 
300
code coverage analysis.  If under-cover is left out or not set,
 
301
coverage analysis is disabled.  The result of the code coverage
 
302
is both printed to the erlang shell (the number of covered vs
 
303
uncovered functions in a module) and written to a buffer called
 
304
*<module> coverage* (which shows the source code for the module
 
305
and the number of times each line is covered).
145
306
With prefix arg, compiles for debug and runs tests with the verbose flag set."
146
 
  (interactive)
 
307
  (erlang-eunit-record-recent-compile under-cover)
147
308
  (let ((src-filename  (erlang-eunit-src-filename  buffer-file-name))
148
309
        (test-filename (erlang-eunit-test-filename buffer-file-name)))
149
310
 
151
312
    ;; below, is to ask the question about saving buffers only once,
152
313
    ;; instead of possibly several: one for each file to compile,
153
314
    ;; for instance for both x.erl and x_tests.erl.
154
 
    (save-some-buffers)
 
315
    (save-some-buffers erlang-eunit-autosave)
155
316
    (flet ((save-some-buffers (&optional any) nil))
156
317
 
157
318
      ;; Compilation of the source file is mandatory (the file must
159
320
      ;; test file on the other hand, is optional, since eunit tests may
160
321
      ;; be placed in the source file instead.  Any compilation error
161
322
      ;; will prevent the subsequent steps to be run (hence the `and')
162
 
      (and (erlang-eunit-compile-file src-filename)
 
323
      (and (erlang-eunit-compile-file src-filename under-cover)
163
324
           (if (file-readable-p test-filename)
164
325
               (erlang-eunit-compile-file test-filename)
165
326
             t)
166
 
           (erlang-eunit-run-tests)))))
167
 
 
168
 
(defun erlang-eunit-compile-file (file-path)
 
327
           (apply test-fun test-args)
 
328
           (if under-cover
 
329
               (save-excursion
 
330
                 (set-buffer (find-file-noselect src-filename))
 
331
                 (erlang-eunit-analyze-coverage)))))))
 
332
 
 
333
(defun erlang-eunit-compile-and-run-module-tests-under-cover ()
 
334
  "Compile the source and test files and run the EUnit test suite and measure
 
335
code coverage.
 
336
 
 
337
With prefix arg, compiles for debug and runs tests with the verbose flag set."
 
338
  (interactive)
 
339
  (let ((module-name (erlang-add-quotes-if-needed
 
340
                      (erlang-eunit-source-module-name buffer-file-name))))
 
341
    (erlang-eunit-compile-and-test
 
342
     'erlang-eunit-run-module-tests (list module-name) t)))
 
343
 
 
344
(defun erlang-eunit-compile-file (file-path &optional under-cover)
169
345
  (if (file-readable-p file-path)
170
346
      (save-excursion
171
 
        (set-buffer (find-file-noselect file-path))
172
 
        (erlang-compile)
173
 
        (erlang-eunit-last-compilation-successful-p))
 
347
        (set-buffer (find-file-noselect file-path))
 
348
        ;; In order to run a code coverage analysis on a
 
349
        ;; module, we have two options:
 
350
        ;;
 
351
        ;; * either compile the module with cover:compile instead of the
 
352
        ;;   regular compiler
 
353
        ;;
 
354
        ;; * or first compile the module with the regular compiler (but
 
355
        ;;   *with* debug_info) and then compile it for coverage
 
356
        ;;   analysis using cover:compile_beam.
 
357
        ;;
 
358
        ;; We could accomplish the first by changing the
 
359
        ;; erlang-compile-erlang-function to cover:compile, but there's
 
360
        ;; a risk that that's used for other purposes.  Therefore, a
 
361
        ;; safer alternative (although with more steps) is to add
 
362
        ;; debug_info to the list of compiler options and go for the
 
363
        ;; second alternative.
 
364
        (if under-cover
 
365
            (erlang-eunit-cover-compile)
 
366
          (erlang-compile))
 
367
        (erlang-eunit-last-compilation-successful-p))
174
368
    (let ((msg (format "Could not read %s" file-path)))
175
 
      (erlang-eunit-inferior-erlang-send-command 
 
369
      (erlang-eunit-inferior-erlang-send-command
176
370
       (format "%% WARNING: %s" msg))
177
371
      (error msg))))
178
 
  
 
372
 
179
373
(defun erlang-eunit-last-compilation-successful-p ()
180
374
  (save-excursion
181
375
    (set-buffer inferior-erlang-buffer)
184
378
     (lambda (re) (let ((continue t)
185
379
                        (result   t))
186
380
                    (while continue ; ignore warnings, stop at errors
187
 
                      (if (re-search-forward re (point-max) t) 
 
381
                      (if (re-search-forward re (point-max) t)
188
382
                          (if (erlang-eunit-is-compilation-warning)
189
383
                              t
190
384
                            (setq result nil)
195
389
     (mapcar (lambda (e) (car e)) erlang-error-regexp-alist))))
196
390
 
197
391
(defun erlang-eunit-is-compilation-warning ()
198
 
  (erlang-eunit-string-match-p 
 
392
  (erlang-eunit-string-match-p
199
393
   "[0-9]+: Warning:"
200
394
   (buffer-substring (line-beginning-position) (line-end-position))))
201
395
 
221
415
;;; Key bindings
222
416
;;;====================================================================
223
417
 
224
 
(defvar erlang-eunit-toggle-src-and-test-file-other-window-key "\C-c\C-et"
225
 
  "*Key to which the `erlang-eunit-toggle-src-and-test-file-other-window' 
226
 
function will be bound.")
227
 
(defvar erlang-eunit-compile-and-run-tests-key "\C-c\C-ek"
228
 
  "*Key to which the `erlang-eunit-compile-and-run-tests'
229
 
function will be bound.")
 
418
(defconst erlang-eunit-key-bindings
 
419
  '(("\C-c\C-et" erlang-eunit-toggle-src-and-test-file-other-window)
 
420
    ("\C-c\C-ek" erlang-eunit-compile-and-run-module-tests)
 
421
    ("\C-c\C-ej" erlang-eunit-compile-and-run-current-test)
 
422
    ("\C-c\C-el" erlang-eunit-compile-and-run-recent)
 
423
    ("\C-c\C-ec" erlang-eunit-compile-and-run-module-tests-under-cover)
 
424
    ("\C-c\C-ev" erlang-eunit-cover-compile)
 
425
    ("\C-c\C-ea" erlang-eunit-analyze-coverage)))
230
426
 
231
427
(defun erlang-eunit-add-key-bindings ()
232
 
  (erlang-eunit-ensure-keymap-for-key
233
 
   erlang-eunit-toggle-src-and-test-file-other-window-key)
234
 
  (local-set-key erlang-eunit-toggle-src-and-test-file-other-window-key
235
 
                 'erlang-eunit-toggle-src-and-test-file-other-window)
236
 
  (erlang-eunit-ensure-keymap-for-key
237
 
   erlang-eunit-compile-and-run-tests-key)
238
 
  (local-set-key erlang-eunit-compile-and-run-tests-key
239
 
                 'erlang-eunit-compile-and-run-tests))
 
428
  (dolist (binding erlang-eunit-key-bindings)
 
429
    (erlang-eunit-bind-key (car binding) (cadr binding))))
 
430
 
 
431
(defun erlang-eunit-bind-key (key function)
 
432
  (erlang-eunit-ensure-keymap-for-key key)
 
433
  (local-set-key key function))
240
434
 
241
435
(defun erlang-eunit-ensure-keymap-for-key (key-seq)
242
436
  (let ((prefix-keys (butlast (append key-seq nil)))