mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-23 04:53:12 -08:00
* test/src/comp-tests.el (comp-tests-make-insn-checker): New function splitting logic from `comp-tests-tco-checker' to have it more general. (comp-tests-tco-checker): Make use of `comp-tests-make-insn-checker'.
643 lines
22 KiB
EmacsLisp
643 lines
22 KiB
EmacsLisp
;;; comp-tests.el --- unit tests for src/comp.c -*- lexical-binding: t; -*-
|
||
|
||
;; Copyright (C) 2019-2020 Free Software Foundation, Inc.
|
||
|
||
;; Author: Andrea Corallo <akrl@sdf.org>
|
||
|
||
;; This file is part of GNU Emacs.
|
||
|
||
;; GNU Emacs 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 3 of the License, or
|
||
;; (at your option) any later version.
|
||
|
||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
;; GNU General Public License for more details.
|
||
|
||
;; You should have received a copy of the GNU General Public License
|
||
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
|
||
|
||
;;; Commentary:
|
||
|
||
;; Unit tests for src/comp.c.
|
||
|
||
;;; Code:
|
||
|
||
(require 'ert)
|
||
(require 'cl-lib)
|
||
(require 'comp)
|
||
|
||
(defconst comp-test-directory (file-name-directory (or load-file-name
|
||
buffer-file-name)))
|
||
(defconst comp-test-src
|
||
(concat comp-test-directory "comp-test-funcs.el"))
|
||
|
||
(defconst comp-test-dyn-src
|
||
(concat comp-test-directory "comp-test-funcs-dyn.el"))
|
||
|
||
(message "Compiling tests...")
|
||
(load (native-compile comp-test-src))
|
||
(load (native-compile comp-test-dyn-src))
|
||
|
||
|
||
|
||
(ert-deftest comp-tests-bootstrap ()
|
||
"Compile the compiler and load it to compile it-self.
|
||
Check that the resulting binaries do not differ."
|
||
(let* ((comp-src (concat comp-test-directory
|
||
"../../lisp/emacs-lisp/comp.el"))
|
||
(comp1-src (make-temp-file "stage1-" nil ".el"))
|
||
(comp2-src (make-temp-file "stage2-" nil ".el"))
|
||
;; Can't use debug symbols.
|
||
(comp-debug 0))
|
||
(copy-file comp-src comp1-src t)
|
||
(copy-file comp-src comp2-src t)
|
||
(load (concat comp-src "c") nil nil t t)
|
||
(should-not (subr-native-elisp-p (symbol-function #'native-compile)))
|
||
(message "Compiling stage1...")
|
||
(let ((comp1-eln (native-compile comp1-src)))
|
||
(load comp1-eln nil nil t t)
|
||
(should (subr-native-elisp-p (symbol-function 'native-compile)))
|
||
(message "Compiling stage2...")
|
||
(let ((comp2-eln (native-compile comp2-src)))
|
||
(message "Comparing %s %s" comp1-eln comp2-eln)
|
||
(should (= (call-process "cmp" nil nil nil comp1-eln comp2-eln) 0))))))
|
||
|
||
(ert-deftest comp-tests-provide ()
|
||
"Testing top level provide."
|
||
(should (featurep 'comp-test-funcs)))
|
||
|
||
(ert-deftest comp-tests-varref ()
|
||
"Testing varref."
|
||
(should (= (comp-tests-varref-f) 3)))
|
||
|
||
(ert-deftest comp-tests-list ()
|
||
"Testing cons car cdr."
|
||
(should (equal (comp-tests-list-f) '(1 2 3)))
|
||
(should (equal (comp-tests-list2-f 1 2 3) '(1 2 3)))
|
||
(should (= (comp-tests-car-f '(1 . 2)) 1))
|
||
(should (null (comp-tests-car-f nil)))
|
||
(should-error (comp-tests-car-f 3)
|
||
:type 'wrong-type-argument)
|
||
(should (= (comp-tests-cdr-f '(1 . 2)) 2))
|
||
(should (null (comp-tests-cdr-f nil)))
|
||
(should-error (comp-tests-cdr-f 3)
|
||
:type 'wrong-type-argument)
|
||
(should (= (comp-tests-car-safe-f '(1 . 2)) 1))
|
||
(should (null (comp-tests-car-safe-f 'a)))
|
||
(should (= (comp-tests-cdr-safe-f '(1 . 2)) 2))
|
||
(should (null (comp-tests-cdr-safe-f 'a))))
|
||
|
||
(ert-deftest comp-tests-cons-car-cdr ()
|
||
"Testing cons car cdr."
|
||
(should (= (comp-tests-cons-car-f) 1))
|
||
(should (= (comp-tests-cons-cdr-f 3) 3)))
|
||
|
||
(ert-deftest comp-tests-varset ()
|
||
"Testing varset."
|
||
(comp-tests-varset0-f)
|
||
(should (= comp-tests-var1 55))
|
||
|
||
(should (= (comp-tests-varset1-f) 4))
|
||
(should (= comp-tests-var1 66)))
|
||
|
||
(ert-deftest comp-tests-length ()
|
||
"Testing length."
|
||
(should (= (comp-tests-length-f) 3)))
|
||
|
||
(ert-deftest comp-tests-aref-aset ()
|
||
"Testing aref and aset."
|
||
(should (= (comp-tests-aref-aset-f) 100)))
|
||
|
||
(ert-deftest comp-tests-symbol-value ()
|
||
"Testing aref and aset."
|
||
(should (= (comp-tests-symbol-value-f) 3)))
|
||
|
||
(ert-deftest comp-tests-concat ()
|
||
"Testing concatX opcodes."
|
||
(should (string= (comp-tests-concat-f "bar") "abcdabcabfoobar")))
|
||
|
||
(ert-deftest comp-tests-ffuncall ()
|
||
"Test calling conventions."
|
||
|
||
;; (defun comp-tests-ffuncall-caller-f ()
|
||
;; (comp-tests-ffuncall-callee-f 1 2 3))
|
||
|
||
;; (should (equal (comp-tests-ffuncall-caller-f) '(1 2 3)))
|
||
|
||
;; ;; After it gets compiled
|
||
;; (native-compile #'comp-tests-ffuncall-callee-f)
|
||
;; (should (equal (comp-tests-ffuncall-caller-f) '(1 2 3)))
|
||
|
||
;; ;; Recompiling the caller once with callee already compiled
|
||
;; (defun comp-tests-ffuncall-caller-f ()
|
||
;; (comp-tests-ffuncall-callee-f 1 2 3))
|
||
;; (should (equal (comp-tests-ffuncall-caller-f) '(1 2 3)))
|
||
|
||
(should (equal (comp-tests-ffuncall-callee-optional-f 1 2 3 4)
|
||
'(1 2 3 4)))
|
||
(should (equal (comp-tests-ffuncall-callee-optional-f 1 2 3)
|
||
'(1 2 3 nil)))
|
||
(should (equal (comp-tests-ffuncall-callee-optional-f 1 2)
|
||
'(1 2 nil nil)))
|
||
|
||
(should (equal (comp-tests-ffuncall-callee-rest-f 1 2)
|
||
'(1 2 nil)))
|
||
(should (equal (comp-tests-ffuncall-callee-rest-f 1 2 3)
|
||
'(1 2 (3))))
|
||
(should (equal (comp-tests-ffuncall-callee-rest-f 1 2 3 4)
|
||
'(1 2 (3 4))))
|
||
|
||
(should (equal (comp-tests-ffuncall-callee-more8-f 1 2 3 4 5 6 7 8 9 10)
|
||
'(1 2 3 4 5 6 7 8 9 10)))
|
||
|
||
(should (equal (comp-tests-ffuncall-callee-more8-rest-f 1 2 3 4 5 6 7 8 9 10 11)
|
||
'(1 2 3 4 5 6 7 8 9 (10 11))))
|
||
|
||
(should (equal (comp-tests-ffuncall-native-f) [nil]))
|
||
|
||
(should (equal (comp-tests-ffuncall-native-rest-f) [1 2 3]))
|
||
|
||
(should (equal (comp-tests-ffuncall-apply-many-f '(1 2 3))
|
||
'(1 2 3)))
|
||
|
||
(should (= (comp-tests-ffuncall-lambda-f 1) 2)))
|
||
|
||
(ert-deftest comp-tests-jump-table ()
|
||
"Testing jump tables"
|
||
(should (eq (comp-tests-jump-table-1-f 'x) 'a))
|
||
(should (eq (comp-tests-jump-table-1-f 'y) 'b))
|
||
(should (eq (comp-tests-jump-table-1-f 'xxx) 'c))
|
||
|
||
;; Jump table not with eq as test
|
||
(should (eq (comp-tests-jump-table-2-f "aaa") 'a))
|
||
(should (eq (comp-tests-jump-table-2-f "bbb") 'b)))
|
||
|
||
(ert-deftest comp-tests-conditionals ()
|
||
"Testing conditionals."
|
||
(should (= (comp-tests-conditionals-1-f t) 1))
|
||
(should (= (comp-tests-conditionals-1-f nil) 2))
|
||
(should (= (comp-tests-conditionals-2-f t) 1340))
|
||
(should (eq (comp-tests-conditionals-2-f nil) nil)))
|
||
|
||
(ert-deftest comp-tests-fixnum ()
|
||
"Testing some fixnum inline operation."
|
||
(should (= (comp-tests-fixnum-1-minus-f 10) 9))
|
||
(should (= (comp-tests-fixnum-1-minus-f most-negative-fixnum)
|
||
(1- most-negative-fixnum)))
|
||
(should-error (comp-tests-fixnum-1-minus-f 'a)
|
||
:type 'wrong-type-argument)
|
||
(should (= (comp-tests-fixnum-1-plus-f 10) 11))
|
||
(should (= (comp-tests-fixnum-1-plus-f most-positive-fixnum)
|
||
(1+ most-positive-fixnum)))
|
||
(should-error (comp-tests-fixnum-1-plus-f 'a)
|
||
:type 'wrong-type-argument)
|
||
(should (= (comp-tests-fixnum-minus-f 10) -10))
|
||
(should (= (comp-tests-fixnum-minus-f most-negative-fixnum)
|
||
(- most-negative-fixnum)))
|
||
(should-error (comp-tests-fixnum-minus-f 'a)
|
||
:type 'wrong-type-argument))
|
||
|
||
(ert-deftest comp-tests-type-hints ()
|
||
"Just test compiler hints are transparent in this case."
|
||
;; FIXME we should really check they are also effective.
|
||
(should (= (comp-tests-hint-fixnum-f 3) 4))
|
||
(should (= (comp-tests-hint-cons-f (cons 1 2)) 1)))
|
||
|
||
(ert-deftest comp-tests-arith-comp ()
|
||
"Testing arithmetic comparisons."
|
||
(should (eq (comp-tests-eqlsign-f 4 3) nil))
|
||
(should (eq (comp-tests-eqlsign-f 3 3) t))
|
||
(should (eq (comp-tests-eqlsign-f 2 3) nil))
|
||
(should (eq (comp-tests-gtr-f 4 3) t))
|
||
(should (eq (comp-tests-gtr-f 3 3) nil))
|
||
(should (eq (comp-tests-gtr-f 2 3) nil))
|
||
(should (eq (comp-tests-lss-f 4 3) nil))
|
||
(should (eq (comp-tests-lss-f 3 3) nil))
|
||
(should (eq (comp-tests-lss-f 2 3) t))
|
||
(should (eq (comp-tests-les-f 4 3) nil))
|
||
(should (eq (comp-tests-les-f 3 3) t))
|
||
(should (eq (comp-tests-les-f 2 3) t))
|
||
(should (eq (comp-tests-geq-f 4 3) t))
|
||
(should (eq (comp-tests-geq-f 3 3) t))
|
||
(should (eq (comp-tests-geq-f 2 3) nil)))
|
||
|
||
(ert-deftest comp-tests-setcarcdr ()
|
||
"Testing setcar setcdr."
|
||
(should (equal (comp-tests-setcar-f '(10 . 10) 3) '(3 . 10)))
|
||
(should (equal (comp-tests-setcdr-f '(10 . 10) 3) '(10 . 3)))
|
||
(should-error (comp-tests-setcar-f 3 10)
|
||
:type 'wrong-type-argument)
|
||
(should-error (comp-tests-setcdr-f 3 10)
|
||
:type 'wrong-type-argument))
|
||
|
||
(ert-deftest comp-tests-bubble-sort ()
|
||
"Run bubble sort."
|
||
(let* ((list1 (mapcar #'random (make-list 1000 most-positive-fixnum)))
|
||
(list2 (copy-sequence list1)))
|
||
(should (equal (comp-bubble-sort-f list1)
|
||
(sort list2 #'<)))))
|
||
|
||
(ert-deftest comp-test-apply ()
|
||
"Test some inlined list functions."
|
||
(should (eq (comp-tests-consp-f '(1)) t))
|
||
(should (eq (comp-tests-consp-f 1) nil))
|
||
(let ((x (cons 1 2)))
|
||
(should (= (comp-tests-setcar2-f x) 3))
|
||
(should (equal x '(3 . 2)))))
|
||
|
||
(ert-deftest comp-tests-num-inline ()
|
||
"Test some inlined number functions."
|
||
(should (eq (comp-tests-integerp-f 1) t))
|
||
(should (eq (comp-tests-integerp-f '(1)) nil))
|
||
(should (eq (comp-tests-integerp-f 3.5) nil))
|
||
(should (eq (comp-tests-integerp-f (1+ most-negative-fixnum)) t))
|
||
|
||
(should (eq (comp-tests-numberp-f 1) t))
|
||
(should (eq (comp-tests-numberp-f 'a) nil))
|
||
(should (eq (comp-tests-numberp-f 3.5) t)))
|
||
|
||
(ert-deftest comp-tests-stack ()
|
||
"Test some stack operation."
|
||
(should (= (comp-tests-discardn-f 10) 2))
|
||
(should (string= (with-temp-buffer
|
||
(comp-tests-insertn-f "a" "b" "c" "d")
|
||
(buffer-string))
|
||
"abcd")))
|
||
|
||
(ert-deftest comp-tests-non-locals ()
|
||
"Test non locals."
|
||
(should (string= (comp-tests-condition-case-0-f)
|
||
"arith-error Arithmetic error catched"))
|
||
(should (string= (comp-tests-condition-case-1-f)
|
||
"error foo catched"))
|
||
(should (= (comp-tests-catch-f
|
||
(lambda () (throw 'foo 3)))
|
||
3))
|
||
(should (= (catch 'foo
|
||
(comp-tests-throw-f 3)))))
|
||
|
||
(ert-deftest comp-tests-gc ()
|
||
"Try to do some longer computation to let the gc kick in."
|
||
(dotimes (_ 100000)
|
||
(comp-tests-cons-cdr-f 3))
|
||
(should (= (comp-tests-cons-cdr-f 3) 3)))
|
||
|
||
(ert-deftest comp-tests-buffer ()
|
||
(should (string= (comp-tests-buff0-f) "foo")))
|
||
|
||
(ert-deftest comp-tests-lambda-return ()
|
||
(let ((f (comp-tests-lambda-return-f)))
|
||
(should (subr-native-elisp-p f))
|
||
(should (= (funcall f 3) 4))))
|
||
|
||
(ert-deftest comp-tests-recursive ()
|
||
(should (= (comp-tests-fib-f 10) 55)))
|
||
|
||
(ert-deftest comp-tests-macro ()
|
||
"Just check we can define macros"
|
||
(should (macrop (symbol-function 'comp-tests-macro-m))))
|
||
|
||
(ert-deftest comp-tests-string-trim ()
|
||
(should (string= (comp-tests-string-trim-f "dsaf ") "dsaf")))
|
||
|
||
(ert-deftest comp-tests-trampoline-removal ()
|
||
;; This tests that we can can call primitives with no dedicated bytecode.
|
||
;; At speed >= 2 the trampoline will not be used.
|
||
(should (hash-table-p (comp-tests-trampoline-removal-f))))
|
||
|
||
(ert-deftest comp-tests-signal ()
|
||
(should (equal (condition-case err
|
||
(comp-tests-signal-f)
|
||
(t err))
|
||
'(foo . t))))
|
||
|
||
(ert-deftest comp-tests-func-call-removal ()
|
||
;; See `comp-propagate-insn' `comp-function-call-remove'.
|
||
(should (= (comp-tests-func-call-removal-f) 1)))
|
||
|
||
(ert-deftest comp-tests-doc ()
|
||
(should (string= (documentation #'comp-tests-doc-f)
|
||
"A nice docstring"))
|
||
(should (string-match "\\.*.eln\\'" (symbol-file #'comp-tests-doc-f))))
|
||
|
||
(ert-deftest comp-test-interactive-form ()
|
||
(should (equal (interactive-form #'comp-test-interactive-form0-f)
|
||
'(interactive "D")))
|
||
(should (equal (interactive-form #'comp-test-interactive-form1-f)
|
||
'(interactive '(1 2))))
|
||
(should (equal (interactive-form #'comp-test-interactive-form2-f)
|
||
'(interactive nil)))
|
||
(should (cl-every #'commandp '(comp-test-interactive-form0-f
|
||
comp-test-interactive-form1-f
|
||
comp-test-interactive-form2-f)))
|
||
(should-not (commandp #'comp-tests-doc-f)))
|
||
|
||
(ert-deftest comp-tests-free-fun ()
|
||
"Check we are able to compile a single function."
|
||
(eval '(defun comp-tests-free-fun-f ()
|
||
"Some doc."
|
||
(interactive)
|
||
3)
|
||
t)
|
||
(load (native-compile #'comp-tests-free-fun-f))
|
||
|
||
(should (subr-native-elisp-p (symbol-function #'comp-tests-free-fun-f)))
|
||
(should (= (comp-tests-free-fun-f) 3))
|
||
(should (string= (documentation #'comp-tests-free-fun-f)
|
||
"Some doc."))
|
||
(should (commandp #'comp-tests-free-fun-f))
|
||
(should (equal (interactive-form #'comp-tests-free-fun-f)
|
||
'(interactive))))
|
||
|
||
(ert-deftest comp-test-40187 ()
|
||
"Check function name shadowing.
|
||
https://lists.gnu.org/archive/html/bug-gnu-emacs/2020-03/msg00914.html."
|
||
(should (eq (comp-test-40187-1-f) 'foo))
|
||
(should (eq (comp-test-40187-2-f) 'bar)))
|
||
|
||
(ert-deftest comp-test-speed--1 ()
|
||
"Check that at speed -1 we do not native compile."
|
||
(should (= (comp-test-speed--1-f) 3))
|
||
(should-not (subr-native-elisp-p (symbol-function #'comp-test-speed--1-f))))
|
||
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;
|
||
;; Tromey's tests. ;;
|
||
;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
(ert-deftest comp-consp ()
|
||
(should-not (comp-test-consp 23))
|
||
(should-not (comp-test-consp nil))
|
||
(should (comp-test-consp '(1 . 2))))
|
||
|
||
(ert-deftest comp-listp ()
|
||
(should-not (comp-test-listp 23))
|
||
(should (comp-test-listp nil))
|
||
(should (comp-test-listp '(1 . 2))))
|
||
|
||
(ert-deftest comp-stringp ()
|
||
(should-not (comp-test-stringp 23))
|
||
(should-not (comp-test-stringp nil))
|
||
(should (comp-test-stringp "hi")))
|
||
|
||
(ert-deftest comp-symbolp ()
|
||
(should-not (comp-test-symbolp 23))
|
||
(should-not (comp-test-symbolp "hi"))
|
||
(should (comp-test-symbolp 'whatever)))
|
||
|
||
(ert-deftest comp-integerp ()
|
||
(should (comp-test-integerp 23))
|
||
(should-not (comp-test-integerp 57.5))
|
||
(should-not (comp-test-integerp "hi"))
|
||
(should-not (comp-test-integerp 'whatever)))
|
||
|
||
(ert-deftest comp-numberp ()
|
||
(should (comp-test-numberp 23))
|
||
(should (comp-test-numberp 57.5))
|
||
(should-not (comp-test-numberp "hi"))
|
||
(should-not (comp-test-numberp 'whatever)))
|
||
|
||
(ert-deftest comp-add1 ()
|
||
(should (eq (comp-test-add1 23) 24))
|
||
(should (eq (comp-test-add1 -17) -16))
|
||
(should (eql (comp-test-add1 1.0) 2.0))
|
||
(should-error (comp-test-add1 nil)
|
||
:type 'wrong-type-argument))
|
||
|
||
(ert-deftest comp-sub1 ()
|
||
(should (eq (comp-test-sub1 23) 22))
|
||
(should (eq (comp-test-sub1 -17) -18))
|
||
(should (eql (comp-test-sub1 1.0) 0.0))
|
||
(should-error (comp-test-sub1 nil)
|
||
:type 'wrong-type-argument))
|
||
|
||
(ert-deftest comp-negate ()
|
||
(should (eq (comp-test-negate 23) -23))
|
||
(should (eq (comp-test-negate -17) 17))
|
||
(should (eql (comp-test-negate 1.0) -1.0))
|
||
(should-error (comp-test-negate nil)
|
||
:type 'wrong-type-argument))
|
||
|
||
(ert-deftest comp-not ()
|
||
(should (eq (comp-test-not 23) nil))
|
||
(should (eq (comp-test-not nil) t))
|
||
(should (eq (comp-test-not t) nil)))
|
||
|
||
(ert-deftest comp-bobp-and-eobp ()
|
||
(with-temp-buffer
|
||
(should (comp-test-bobp))
|
||
(should (comp-test-eobp))
|
||
(insert "hi")
|
||
(goto-char (point-min))
|
||
(should (eq (comp-test-point-min) (point-min)))
|
||
(should (eq (comp-test-point) (point-min)))
|
||
(should (comp-test-bobp))
|
||
(should-not (comp-test-eobp))
|
||
(goto-char (point-max))
|
||
(should (eq (comp-test-point-max) (point-max)))
|
||
(should (eq (comp-test-point) (point-max)))
|
||
(should-not (comp-test-bobp))
|
||
(should (comp-test-eobp))))
|
||
|
||
(ert-deftest comp-car-cdr ()
|
||
(let ((pair '(1 . b)))
|
||
(should (eq (comp-test-car pair) 1))
|
||
(should (eq (comp-test-car nil) nil))
|
||
(should-error (comp-test-car 23)
|
||
:type 'wrong-type-argument)
|
||
(should (eq (comp-test-cdr pair) 'b))
|
||
(should (eq (comp-test-cdr nil) nil))
|
||
(should-error (comp-test-cdr 23)
|
||
:type 'wrong-type-argument)))
|
||
|
||
(ert-deftest comp-car-cdr-safe ()
|
||
(let ((pair '(1 . b)))
|
||
(should (eq (comp-test-car-safe pair) 1))
|
||
(should (eq (comp-test-car-safe nil) nil))
|
||
(should (eq (comp-test-car-safe 23) nil))
|
||
(should (eq (comp-test-cdr-safe pair) 'b))
|
||
(should (eq (comp-test-cdr-safe nil) nil))
|
||
(should (eq (comp-test-cdr-safe 23) nil))))
|
||
|
||
(ert-deftest comp-eq ()
|
||
(should (comp-test-eq 'a 'a))
|
||
(should (comp-test-eq 5 5))
|
||
(should-not (comp-test-eq 'a 'b)))
|
||
|
||
(ert-deftest comp-if ()
|
||
(should (eq (comp-test-if 'a 'b) 'a))
|
||
(should (eq (comp-test-if 0 23) 0))
|
||
(should (eq (comp-test-if nil 'b) 'b)))
|
||
|
||
(ert-deftest comp-and ()
|
||
(should (eq (comp-test-and 'a 'b) 'b))
|
||
(should (eq (comp-test-and 0 23) 23))
|
||
(should (eq (comp-test-and nil 'b) nil)))
|
||
|
||
(ert-deftest comp-or ()
|
||
(should (eq (comp-test-or 'a 'b) 'a))
|
||
(should (eq (comp-test-or 0 23) 0))
|
||
(should (eq (comp-test-or nil 'b) 'b)))
|
||
|
||
(ert-deftest comp-save-excursion ()
|
||
(with-temp-buffer
|
||
(comp-test-save-excursion)
|
||
(should (eq (point) (point-min)))
|
||
(should (eq (comp-test-current-buffer) (current-buffer)))))
|
||
|
||
(ert-deftest comp-> ()
|
||
(should (eq (comp-test-> 0 23) nil))
|
||
(should (eq (comp-test-> 23 0) t)))
|
||
|
||
(ert-deftest comp-catch ()
|
||
(should (eq (comp-test-catch 0 1 2 3 4) nil))
|
||
(should (eq (comp-test-catch 20 21 22 23 24 25 26 27 28) 24)))
|
||
|
||
(ert-deftest comp-memq ()
|
||
(should (equal (comp-test-memq 0 '(5 4 3 2 1 0)) '(0)))
|
||
(should (eq (comp-test-memq 72 '(5 4 3 2 1 0)) nil)))
|
||
|
||
(ert-deftest comp-listN ()
|
||
(should (equal (comp-test-listN 57)
|
||
'(57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57))))
|
||
|
||
(ert-deftest comp-concatN ()
|
||
(should (equal (comp-test-concatN "x") "xxxxxx")))
|
||
|
||
(ert-deftest comp-opt-rest ()
|
||
(should (equal (comp-test-opt-rest 1) '(1 nil nil)))
|
||
(should (equal (comp-test-opt-rest 1 2) '(1 2 nil)))
|
||
(should (equal (comp-test-opt-rest 1 2 3) '(1 2 (3))))
|
||
(should (equal (comp-test-opt-rest 1 2 56 57 58)
|
||
'(1 2 (56 57 58)))))
|
||
|
||
(ert-deftest comp-opt ()
|
||
(should (equal (comp-test-opt 23) '(23)))
|
||
(should (equal (comp-test-opt 23 24) '(23 . 24)))
|
||
(should-error (comp-test-opt)
|
||
:type 'wrong-number-of-arguments)
|
||
(should-error (comp-test-opt nil 24 97)
|
||
:type 'wrong-number-of-arguments))
|
||
|
||
(ert-deftest comp-unwind-protect ()
|
||
(comp-test-unwind-protect 'ignore)
|
||
(should (eq comp-test-up-val 999))
|
||
(condition-case nil
|
||
(comp-test-unwind-protect (lambda () (error "HI")))
|
||
(error
|
||
nil))
|
||
(should (eq comp-test-up-val 999)))
|
||
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;; Tests for dynamic scope. ;;
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
(ert-deftest comp-tests-dynamic-ffuncall ()
|
||
"Test calling convention for dynamic binding."
|
||
|
||
(should (equal (comp-tests-ffuncall-callee-dyn-f 1 2)
|
||
'(1 2)))
|
||
|
||
(should (equal (comp-tests-ffuncall-callee-opt-dyn-f 1 2 3 4)
|
||
'(1 2 3 4)))
|
||
(should (equal (comp-tests-ffuncall-callee-opt-dyn-f 1 2 3)
|
||
'(1 2 3 nil)))
|
||
(should (equal (comp-tests-ffuncall-callee-opt-dyn-f 1 2)
|
||
'(1 2 nil nil)))
|
||
|
||
(should (equal (comp-tests-ffuncall-callee-rest-dyn-f 1 2)
|
||
'(1 2 nil)))
|
||
(should (equal (comp-tests-ffuncall-callee-rest-dyn-f 1 2 3)
|
||
'(1 2 (3))))
|
||
(should (equal (comp-tests-ffuncall-callee-rest-dyn-f 1 2 3 4)
|
||
'(1 2 (3 4))))
|
||
|
||
(should (equal (comp-tests-ffuncall-callee-opt-rest-dyn-f 1 2)
|
||
'(1 2 nil nil)))
|
||
(should (equal (comp-tests-ffuncall-callee-opt-rest-dyn-f 1 2 3)
|
||
'(1 2 3 nil)))
|
||
(should (equal (comp-tests-ffuncall-callee-opt-rest-dyn-f 1 2 3 4)
|
||
'(1 2 3 (4)))))
|
||
|
||
(ert-deftest comp-tests-dynamic-arity ()
|
||
"Test func-arity on dynamic scope functions."
|
||
(should (equal '(2 . 2)
|
||
(func-arity #'comp-tests-ffuncall-callee-dyn-f)))
|
||
(should (equal '(2 . 4)
|
||
(func-arity #'comp-tests-ffuncall-callee-opt-dyn-f)))
|
||
(should (equal '(2 . many)
|
||
(func-arity #'comp-tests-ffuncall-callee-rest-dyn-f)))
|
||
(should (equal '(2 . many)
|
||
(func-arity #'comp-tests-ffuncall-callee-opt-rest-dyn-f))))
|
||
|
||
(ert-deftest comp-tests-cl-macro-exp ()
|
||
"Verify CL macro expansion (bug#42088)."
|
||
(should (equal (comp-tests-cl-macro-exp-f) '(a b))))
|
||
|
||
(ert-deftest comp-tests-cl-uninterned-arg-parse-f ()
|
||
"Verify the parsing of a lambda list with uninterned symbols (bug#42120)."
|
||
(should (equal (comp-tests-cl-uninterned-arg-parse-f 1 2)
|
||
'(1 2))))
|
||
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;; Middle-end specific tests. ;;
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
(defun comp-tests-mentioned-p-1 (x insn)
|
||
(cl-loop for y in insn
|
||
when (cond
|
||
((consp y) (comp-tests-mentioned-p x y))
|
||
((and (comp-mvar-p y) (comp-mvar-const-vld y))
|
||
(equal (comp-mvar-constant y) x))
|
||
(t (equal x y)))
|
||
return t))
|
||
|
||
(defun comp-tests-mentioned-p (x insn)
|
||
"Check if X is actively mentioned in INSN."
|
||
(unless (eq (car-safe insn)
|
||
'comment)
|
||
(comp-tests-mentioned-p-1 x insn)))
|
||
|
||
(defun comp-tests-make-insn-checker (func-name checker)
|
||
"Apply CHECKER to each insn in FUNC-NAME.
|
||
CHECKER should always return nil to have a pass."
|
||
(should-not
|
||
(cl-loop
|
||
named checker-loop
|
||
with func-c-name = (comp-c-func-name func-name "F" t)
|
||
with f = (gethash func-c-name (comp-ctxt-funcs-h comp-ctxt))
|
||
for bb being each hash-value of (comp-func-blocks f)
|
||
do (cl-loop
|
||
for insn in (comp-block-insns bb)
|
||
when (funcall checker insn)
|
||
do (cl-return-from checker-loop 'mentioned)))))
|
||
|
||
(defun comp-tests-tco-checker (_)
|
||
"Check that inside `comp-tests-tco-f' we have no recursion."
|
||
(comp-tests-make-insn-checker
|
||
'comp-tests-tco-f
|
||
(lambda (insn)
|
||
(or (comp-tests-mentioned-p 'comp-tests-tco-f insn)
|
||
(comp-tests-mentioned-p (comp-c-func-name 'comp-tests-tco-f "F" t)
|
||
insn)))))
|
||
|
||
(ert-deftest comp-tests-tco ()
|
||
"Check for tail recursion elimination."
|
||
(let ((comp-speed 3)
|
||
(comp-post-pass-hooks '((comp-tco comp-tests-tco-checker)
|
||
(comp-final comp-tests-tco-checker))))
|
||
(eval '(defun comp-tests-tco-f (a b count)
|
||
(if (= count 0)
|
||
b
|
||
(comp-tests-tco-f (+ a b) a (- count 1))))
|
||
t)
|
||
(load (native-compile #'comp-tests-tco-f))
|
||
(should (subr-native-elisp-p (symbol-function #'comp-tests-tco-f)))
|
||
(should (= (comp-tests-tco-f 1 0 10) 55))))
|
||
|
||
;;; comp-tests.el ends here
|