• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1;;; clang-format-test.el --- unit tests for clang-format.el  -*- lexical-binding: t; -*-
2
3;; Copyright (C) 2017  Google Inc.
4
5;; Author: Philipp Stephani <phst@google.com>
6
7;; Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
8;; See https://llvm.org/LICENSE.txt for license information.
9;; SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
10
11;;; Commentary:
12
13;; Unit tests for clang-format.el. Not run by lit, run as:
14;; emacs -Q -batch -l clang/tools/clang-format/clang-format.el -l clang/tools/clang-format/clang-format-test.el -f ert-run-tests-batch-and-exit
15
16;;; Code:
17
18(require 'clang-format)
19
20(require 'cl-lib)
21(require 'ert)
22(require 'pcase)
23
24(ert-deftest clang-format-buffer--buffer-encoding ()
25  "Tests that encoded text is handled properly."
26  (cl-letf* ((call-process-args nil)
27             ((symbol-function 'call-process-region)
28              (lambda (&rest args)
29                (push args call-process-args)
30                (pcase-exhaustive args
31                  (`(,_start ,_end ,_program ,_delete (,stdout ,_stderr)
32                             ,_display . ,_args)
33                   (with-current-buffer stdout
34                     (insert "<?xml version='1.0'?>
35<replacements xml:space='preserve' incomplete_format='false'>
36<replacement offset='4' length='0'> </replacement>
37<replacement offset='10' length='0'> </replacement>
38</replacements>
39"))
40                   0)))))
41    (with-temp-buffer
42      (let ((buffer-file-name "foo.cpp")
43            (buffer-file-coding-system 'utf-8-with-signature-dos)
44            (default-process-coding-system 'latin-1-unix))
45        (insert "ä =ö;\nü= ß;\n")
46        (goto-char (point-min))
47        (end-of-line)
48        (clang-format-buffer))
49      (should (equal (buffer-string) "ä = ö;\nü = ß;\n"))
50      (should (eolp))
51      (should (equal (buffer-substring (point) (point-max))
52                     "\nü = ß;\n")))
53    (should-not (cdr call-process-args))
54    (pcase-exhaustive call-process-args
55      (`((,start ,end ,_program ,delete (,_stdout ,_stderr) ,display . ,args))
56       (should-not start)
57       (should-not end)
58       (should-not delete)
59       (should-not display)
60       (should (equal args
61                      '("-output-replacements-xml" "-assume-filename" "foo.cpp"
62                        "-fallback-style" "none"
63                        ;; Beginning of buffer, no byte-order mark.
64                        "-offset" "0"
65                        ;; We have two lines with 2×2 bytes for the umlauts,
66                        ;; 1 byte for the line ending, and 3 bytes for the
67                        ;; other ASCII characters each.
68                        "-length" "16"
69                        ;; Length of a single line (without line ending).
70                        "-cursor" "7")))))))
71
72(ert-deftest clang-format-buffer--process-encoding ()
73  "Tests that text is sent to the clang-format process in the
74right encoding."
75  (cl-letf* ((hexdump (executable-find "hexdump"))
76             (original-call-process-region
77              (symbol-function 'call-process-region))
78             (call-process-inputs nil)
79             ;; We redirect the input to hexdump so that we have guaranteed
80             ;; ASCII output.
81             ((symbol-function 'call-process-region)
82              (lambda (&rest args)
83                (pcase-exhaustive args
84                  (`(,start ,end ,_program ,_delete (,stdout ,_stderr)
85                            ,_display . ,_args)
86                   (with-current-buffer stdout
87                     (insert "<?xml version='1.0'?>
88<replacements xml:space='preserve' incomplete_format='false'>
89</replacements>
90"))
91                   (let ((stdin (current-buffer)))
92                     (with-temp-buffer
93                       (prog1
94                           (let ((stdout (current-buffer)))
95                             (with-current-buffer stdin
96                               (funcall original-call-process-region
97                                        start end hexdump nil stdout nil
98                                        "-v" "-e" "/1 \"%02x \"")))
99                         (push (buffer-string) call-process-inputs)))))))))
100    (skip-unless hexdump)
101    (with-temp-buffer
102      (let ((buffer-file-name "foo.cpp")
103            (buffer-file-coding-system 'utf-8-with-signature-dos)
104            (default-process-coding-system 'latin-1-unix))
105        (insert "ä\n")
106        (clang-format-buffer))
107      (should (equal (buffer-string) "ä\n"))
108      (should (eobp)))
109    (should (equal call-process-inputs '("c3 a4 0a ")))))
110
111(ert-deftest clang-format-buffer--end-to-end ()
112  "End-to-end test for ‘clang-format-buffer’.
113Actually calls the clang-format binary."
114  (skip-unless (file-executable-p clang-format-executable))
115  (with-temp-buffer
116    (let ((buffer-file-name "foo.cpp")
117          (buffer-file-coding-system 'utf-8-with-signature-dos)
118          (default-process-coding-system 'latin-1-unix))
119      (insert "ä =ö;\nü= ß;\n")
120      (goto-char (point-min))
121      (end-of-line)
122      (clang-format-buffer))
123    (should (equal (buffer-string) "ä = ö;\nü = ß;\n"))
124    (should (eolp))
125    (should (equal (buffer-substring (point) (point-max))
126                   "\nü = ß;\n"))))
127
128;;; clang-format-test.el ends here
129