Skip to content

Commit

Permalink
Merge 3731f1b into cfd1d08
Browse files Browse the repository at this point in the history
  • Loading branch information
CyberShadow committed Nov 12, 2019
2 parents cfd1d08 + 3731f1b commit 7f9986f
Show file tree
Hide file tree
Showing 45 changed files with 2,763 additions and 743 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
*.elc
/.cask/
/tests/*.res.*
10 changes: 6 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,18 @@ matrix:
allow_failures:
- env: EMACS_VERSION=snapshot
env:
- EMACS_VERSION=24.3
- EMACS_VERSION=24.5
- EMACS_VERSION=25.1
- EMACS_VERSION=25.2
- EMACS_VERSION=25.3
- EMACS_VERSION=26.1
- EMACS_VERSION=26.2
- EMACS_VERSION=26.3
- EMACS_VERSION=snapshot
before_install:
# Configure $PATH: Executables are installed to $HOME/bin
- export PATH="$HOME/bin:$PATH"
# Download the makefile to emacs-travis.mk
- wget 'https://raw.githubusercontent.com/flycheck/emacs-travis/master/emacs-travis.mk'
- wget 'https://raw.githubusercontent.com/CyberShadow/emacs-travis/patch-1/emacs-travis.mk'
# Install Emacs (according to $EMACS_VERSION) and Cask
- make -f emacs-travis.mk install_emacs
- make -f emacs-travis.mk install_cask
Expand All @@ -27,5 +30,4 @@ install:
script:
# cask exec ert-runner
- emacs --version
- make compile
- make test
674 changes: 674 additions & 0 deletions COPYING

Large diffs are not rendered by default.

27 changes: 23 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
emacs ?= emacs
all: test

test: clean
cask exec emacs -Q -batch -l d-mode-test.el -l d-mode.el -f ert-run-tests-batch-and-exit
test: test-source test-compiled

test-source: clean
cask exec emacs -Q -batch -l d-mode-test.el -l d-mode.el -f ert-run-tests-batch-and-exit

test-compiled: compile
D_MODE_NO_COVERAGE=1 cask exec emacs -Q -batch -l d-mode-test.el -l d-mode.elc -f ert-run-tests-batch-and-exit

# Generate a coverage report viewable in Emacs.
coverage: clean
rm -f d-mode.elc
D_MODE_COVERAGE=1 cask exec emacs -Q -batch -l d-mode-test.el -l d-mode.el -f ert-run-tests-batch-and-exit

compile:
$(emacs) -Q -batch -f batch-byte-compile d-mode.el
$(emacs) -Q -batch --eval '(setq byte-compile-error-on-warn t)' -f batch-byte-compile d-mode.el

clean:
rm -f d-mode.elc
find tests -name '*.res.*' -delete

# Show just the differences between the actual and expected results.
test-diff:
for f in tests/*.res.* ; do diff --color -u "$${f/.res/}" "$$f" ; done

# Accept any mismatching actual output as the expected output.
test-accept:
for f in tests/*.res.* ; do mv "$$f" "$${f/.res/}" ; done

.PHONY: all test
.PHONY: all test compile clean test-diff test-accept
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@

An Emacs major mode for editing D code.

This mode is currently known to work with Emacs 24 and 25.
This mode is currently known to work with Emacs 25 and 26.
For best results, use Emacs 26.

The best way of installing this major mode, at least for Emacs 24, is to use the packaging system. Add MELPA
The best way of installing this major mode, at least for Emacs 26, is to use the packaging system. Add MELPA
or MELPA Stable to the list of repositories to access this mode. For those who want only formal, tagged
releases use MELPA Stable:

Expand Down
1 change: 1 addition & 0 deletions coverage/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/.resultset.json*
155 changes: 91 additions & 64 deletions d-mode-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2 of the License, or
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
Expand Down Expand Up @@ -49,11 +49,25 @@
;;----------------------------------------------------------------------------
;;; Code:

(when (require 'undercover nil t)
(undercover "d-mode.el"))
(if (getenv "D_MODE_COVERAGE")
(progn
;; Generate a coverage report viewable in Emacs.
(require 'undercover)
(setq undercover-force-coverage t)
(undercover "d-mode.el"
(:report-file "coverage/.resultset.json")
(:report-format 'simplecov)
(:send-report nil))
)
(unless (getenv "D_MODE_NO_COVERAGE")
(when (require 'undercover nil t)
(undercover "d-mode.el"))))

(require 'd-mode nil t)

(def-edebug-spec d--static-if (sexp form &optional form))
(def-edebug-spec d--if-version>= (sexp form &optional form))

(require 'htmlfontify)

(defconst d-test-teststyle
Expand Down Expand Up @@ -84,7 +98,7 @@
(inline-close . 0)
(func-decl-cont . +)
(topmost-intro . 0)
(topmost-intro-cont . c-lineup-topmost-intro-cont)
(topmost-intro-cont . 1)
(member-init-intro . +)
(member-init-cont . c-lineup-multi-inher)
(inher-intro . +)
Expand Down Expand Up @@ -132,13 +146,16 @@
(inlambda . c-lineup-inexpr-block)
(lambda-intro-cont . +)
(inexpr-statement . +)
(inexpr-class . +)))
(inexpr-class . +)
(knr-argdecl-intro . 0)))
(c-echo-syntactic-information-p . t)
(c-indent-comment-alist . nil))
"Style for testing.")

(c-add-style "teststyle" d-test-teststyle)

(defvar-local d-test-orig-filename nil)

(defun make-test-buffer (filename)
(let ((testbuf (get-buffer-create "*d-mode-test*"))
(enable-local-eval t))
Expand All @@ -157,6 +174,7 @@
c-mode-common-hook)
(d-mode))
(hack-local-variables)
(setq-local d-test-orig-filename filename)
testbuf))

(defun kill-test-buffer ()
Expand Down Expand Up @@ -187,29 +205,19 @@
(switch-to-buffer testbuf)
(syntax-ppss (point-max))

(condition-case err
;; extract the run command and expected output if any.
(let* ((contents (buffer-substring-no-properties 1 (point-max)))
(run-str (if (string-match "^// #run: \\(.+\\)$" contents)
(match-string 1 contents)))
(out-str (if (string-match "^// #out: \\(.+\\)$" contents)
(match-string 1 contents))))
(when run-str
(let ((result (eval (car (read-from-string run-str)))))
(when out-str
(let ((expect (car (read-from-string out-str))))
(unless (equal result expect)
(error "\nExpected: %s\nGot : %s" expect result))))))
t)
(error
(set-buffer testbuf)
(buffer-enable-undo testbuf)
(set-buffer-modified-p nil)
(setq error-found-p t)

(message
"Regression found in file %s:\n%s"
filename (error-message-string err))))
;; extract the run command and expected output if any.
(let* ((contents (buffer-substring-no-properties 1 (point-max)))
(run-str (if (string-match "^// #run: \\(.+\\)$" contents)
(match-string 1 contents)))
(out-str (if (string-match "^// #out: \\(.+\\)$" contents)
(match-string 1 contents))))
(when run-str
(let ((result (eval (car (read-from-string run-str)))))
(when out-str
(let ((expect (car (read-from-string out-str))))
(unless (equal result expect)
(error "\nExpected: %s\nGot : %s" expect result))))))
t)

(set-buffer save-buf)
(goto-char save-point)
Expand All @@ -233,24 +241,29 @@ Called from the #run snippet of individual test files."

(require 'imenu)

(defun d-test--imenu-to-lines (x)
"Extracts line numbers from one possibly-nested imenu--index-alist element X."
(if (imenu--subalist-p x)
(apply #'append (mapcar #'d-test--imenu-to-lines (cdr x)))
(list (line-number-at-pos (cdr x)))))

(defun d-test-get-imenu-lines ()
"Get list of line numbers of lines recognized as imenu entries.
Called from the #run snippet of individual test files."
(imenu--make-index-alist t)
(sort
(apply
'append
(mapcar
(lambda (x)
(if (imenu--subalist-p x)
(mapcar
(lambda (x)
(line-number-at-pos (cdr x)))
(cdr x))
(list (line-number-at-pos (cdr x)))))
imenu--index-alist))
'<))
(sort (d-test--imenu-to-lines (cons nil imenu--index-alist)) '<))

(defun d-test-save-result (filename)
"In case of an unexpected result, save it to a file.
FILENAME is the original (versioned) file name."
(write-region
nil nil
(concat
(file-name-sans-extension filename)
".res"
(file-name-extension filename t))))

(defun d-test-indent ()
"Re-indent the current file.
Expand All @@ -261,7 +274,8 @@ If the resulting indentation ends up being different, raise an error."
(error
(let ((orig (buffer-string)))
(let (buffer-read-only)
(c-indent-region (point-min) (point-max)))
(c-indent-region (point-min) (point-max))
(d-test-save-result d-test-orig-filename))
(error (concat "Test case has been indented differently.\n"
"Expected:\n--------------------\n%s\n--------------------\n"
"Got: \n--------------------\n%s\n--------------------\n")
Expand All @@ -281,37 +295,50 @@ the reference file, raise an error."
(default-value 'font-lock-fontify-region-function)))

(let* ((hfy-optimisations '(body-text-only merge-adjacent-tags))
(html-filename (concat filename ".html"))
(actual (with-current-buffer (htmlfontify-buffer nil "test.d") (buffer-string)))
(expected (with-temp-buffer
(insert-file-contents (concat filename ".html"))
(insert-file-contents html-filename)
(buffer-string))))
(unless (equal actual expected)
(with-temp-buffer (insert actual) (d-test-save-result html-filename))
(error (concat "Test case has been fontified differently.\n"
"Expected:\n--------------------\n%s\n--------------------\n"
"Got: \n--------------------\n%s\n--------------------\n")
expected actual))))

(defmacro d-test-deftest (name filename expected-result)
"Define a d-mode test using the given FILENAME.
EXPECTED-RESULT should return t if the test
is expected to succeed, and nil otherwise."
`(ert-deftest ,name ()
:expected-result (if ,expected-result :passed :failed)
(should (do-one-test ,filename))))

;; Run the tests
(d-test-deftest imenu "tests/imenu.d" t)
(d-test-deftest fonts "tests/fonts.d" t)
(d-test-deftest i0021 "tests/I0021.d" t)
(d-test-deftest i0026 "tests/I0026.d" t)
(d-test-deftest i0030 "tests/I0030.d" t)
(d-test-deftest i0035 "tests/I0035.d" (version< "24.4" emacs-version))
(d-test-deftest i0039 "tests/I0039.d" (version< "24.4" emacs-version))
(d-test-deftest i0049 "tests/I0049.d" t)
(d-test-deftest i0064 "tests/I0064.d" t)
(d-test-deftest i0069 "tests/I0069.txt" t)
(d-test-deftest i0072 "tests/I0072.txt" t)
(defun d-test-get-expected-result (filename)
(with-temp-buffer
(insert-file-contents filename)
(let* ((min-ver
(if (re-search-forward "^// #min-version: \\(.+\\)$" nil t)
(match-string 1)
"0")))
(version<= min-ver emacs-version))))

(defmacro d-test-dir (dir)
"Register all test files from DIR with ert."
(apply #'nconc
'(progn)
(mapcar
(lambda (filename)
(let ((path (expand-file-name filename dir)))
(cond
((string-match-p "\\`\\.\\.?\\'" filename)
nil)
((string-match-p "\\.res" filename)
nil)
((string-match-p "\\.\\(d\\|txt\\)\\'" filename)
`((ert-deftest ,(intern (file-name-sans-extension filename)) ()
:expected-result (if (d-test-get-expected-result ,path) :passed :failed)
(should (do-one-test ,path)))))
((string-match-p "\\.d\\.html\\'" filename)
nil)
(t
(message "Ignoring test file with unknown extension: %s" filename)
nil))))
(directory-files dir))))
(d-test-dir "tests")

;;----------------------------------------------------------------------------

Expand Down

0 comments on commit 7f9986f

Please sign in to comment.