* Build ** bootstrapping Libraries that are part of the "bootstrap set" cannot rely on autoloading. Example: =files.el= must ~(eval-when-compile (require 'pcase))~, even though it only uses autoloaded macros. * Tests ** Running Somehow I can never remember how to ask =make= how to run a specific set of tests. tl;dr, running =$testcases_regexp= from =test/$testfile.el=, to test changes in =lisp/$sourcefile.el=: #+begin_src sh make -C test $testfile \ TEST_LOAD_EL=yes \ TEST_BACKTRACE_LINE_LENGTH=nil \ SELECTOR="\"$testcases_regexp\"" \ EMACS_EXTRAOPT="-l ../lisp/$sourcefile.el" #+end_src Relevant bits from test/Makefile: #+begin_src makefile ## filename.log: run tests from filename.el(c) if .log file needs updating ## filename: re-run tests from filename.el(c), with no logging #+end_src #+begin_src makefile # Whether to run tests from .el files in preference to .elc, we do # this by default since it gives nicer stacktraces. # If you just want a pass/fail, setting this to no is much faster. export TEST_LOAD_EL ?= \ $(if $(findstring $(MAKECMDGOALS), all check check-maybe),no,yes) #+end_src #+begin_src makefile TEST_RUN_ERT = --batch --eval '(ert-run-tests-batch-and-exit (quote ${SELECTOR_ACTUAL}))' ${WRITE_LOG} #+end_src #+begin_src makefile ifdef SELECTOR SELECTOR_ACTUAL=$(SELECTOR) #+end_src Selector documentation from ~ert-select-tests~: #+begin_quote Valid SELECTORs: nil -- Selects the empty set. t -- Selects UNIVERSE. :new -- Selects all tests that have not been run yet. :failed, :passed -- Select tests according to their most recent result. :expected, :unexpected -- Select tests according to their most recent result. a string -- A regular expression selecting all tests with matching names. a test -- (i.e., an object of the ert-test data-type) Selects that test. a symbol -- Selects the test that the symbol names, signals an ‘ert-test-unbound’ error if none. (member TESTS...) -- Selects the elements of TESTS, a list of tests or symbols naming tests. (eql TEST) -- Selects TEST, a test or a symbol naming a test. (and SELECTORS...) -- Selects the tests that match all SELECTORS. (or SELECTORS...) -- Selects the tests that match any of the SELECTORS. (not SELECTOR) -- Selects all tests that do not match SELECTOR. (tag TAG) -- Selects all tests that have TAG on their tags list. A tag is an arbitrary label you can apply when you define a test. (satisfies PREDICATE) -- Selects all tests that satisfy PREDICATE. PREDICATE is a function that takes an ert-test object as argument, and returns non-nil if it is selected. #+end_quote ** Writing *** Mocking functions #+begin_src elisp (cl-letf (((symbol-function 'read-something) (lambda (&rest _) "result"))) (some-command)) #+end_src * Third-party packages ** forge *** build Use =config.mk= to set =LOAD_PATH=: #+begin_src makefile find-lib = $(dir $(shell emacs -Q -batch \ -eval "(require 'find-func)" \ -eval "(package-initialize)" \ -eval "(require '$(1))" \ -eval "(princ (find-library-name \"$(1)\"))")) sources = ~/src/emacs/magit/lisp elpa = \ closql \ compat \ dash \ emacsql \ ghub \ markdown-mode \ transient \ treepy \ with-editor \ yaml elpa_dirs = $(foreach d,$(elpa),$(call find-lib,$(d))) LOAD_PATH = $(addprefix -L ,$(elpa_dirs) $(sources)) #+end_src *** load sources ~emacs -Q -L ./lisp~ does not seem to work: after running ~(package-initialize)~, =M-x find-library forge= returns the instance installed under ~package-user-dir~. This can be circumvented with ~(setq pacakge-load-list '((forge nil) all))~. Full command line for easy startup: #+begin_src sh emacs -Q -L ./lisp \ -eval "(setq pacakge-load-list '((forge nil) all))" \ -f package-initialize \ #+end_src