emacs/test/lisp/emacs-lisp/hierarchy-tests.el
Stefan Kangas 2aeff0794a Use lexical-binding in more tests
* test/lib-src/emacsclient-tests.el:
* test/lisp/emacs-lisp/hierarchy-tests.el:
* test/lisp/eshell/eshell-tests.el:
* test/lisp/gnus/gnus-util-tests.el:
* test/lisp/progmodes/js-tests.el:
* test/lisp/textmodes/bibtex-tests.el:
* test/src/editfns-tests.el:
* test/src/fns-tests.el: Use lexical-binding.

* test/lisp/emacs-lisp/hierarchy-tests.el
(hierarchy-leafs-includes-lonely-roots):
* test/src/editfns-tests.el (transpose-test-get-byte-positions):
* test/src/fns-tests.el (fns-tests-func-arity):
Adjust for lexical-binding.
2020-08-29 22:41:51 +02:00

556 lines
24 KiB
EmacsLisp

;;; hierarchy-tests.el --- Tests for hierarchy.el -*- lexical-binding:t -*-
;; Copyright (C) 2017-2019 Damien Cassou
;; Author: Damien Cassou <damien@cassou.me>
;; Maintainer: emacs-devel@gnu.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:
;; Tests for hierarchy.el
;;; Code:
(require 'ert)
(require 'hierarchy)
(defun hierarchy-animals ()
"Create a sorted animal hierarchy."
(let ((parentfn (lambda (item) (cl-case item
(dove 'bird)
(pigeon 'bird)
(bird 'animal)
(dolphin 'animal)
(cow 'animal))))
(hierarchy (hierarchy-new)))
(hierarchy-add-tree hierarchy 'dove parentfn)
(hierarchy-add-tree hierarchy 'pigeon parentfn)
(hierarchy-add-tree hierarchy 'dolphin parentfn)
(hierarchy-add-tree hierarchy 'cow parentfn)
(hierarchy-sort hierarchy)
hierarchy))
(ert-deftest hierarchy-add-one-root ()
(let ((parentfn (lambda (_) nil))
(hierarchy (hierarchy-new)))
(hierarchy-add-tree hierarchy 'animal parentfn)
(should (equal (hierarchy-roots hierarchy) '(animal)))))
(ert-deftest hierarchy-add-one-item-with-parent ()
(let ((parentfn (lambda (item)
(cl-case item
(bird 'animal))))
(hierarchy (hierarchy-new)))
(hierarchy-add-tree hierarchy 'bird parentfn)
(should (equal (hierarchy-roots hierarchy) '(animal)))
(should (equal (hierarchy-children hierarchy 'animal) '(bird)))))
(ert-deftest hierarchy-add-one-item-with-parent-and-grand-parent ()
(let ((parentfn (lambda (item)
(cl-case item
(dove 'bird)
(bird 'animal))))
(hierarchy (hierarchy-new)))
(hierarchy-add-tree hierarchy 'dove parentfn)
(should (equal (hierarchy-roots hierarchy) '(animal)))
(should (equal (hierarchy-children hierarchy 'animal) '(bird)))
(should (equal (hierarchy-children hierarchy 'bird) '(dove)))))
(ert-deftest hierarchy-add-same-root-twice ()
(let ((parentfn (lambda (_) nil))
(hierarchy (hierarchy-new)))
(hierarchy-add-tree hierarchy 'animal parentfn)
(hierarchy-add-tree hierarchy 'animal parentfn)
(should (equal (hierarchy-roots hierarchy) '(animal)))))
(ert-deftest hierarchy-add-same-child-twice ()
(let ((parentfn (lambda (item)
(cl-case item
(bird 'animal))))
(hierarchy (hierarchy-new)))
(hierarchy-add-tree hierarchy 'bird parentfn)
(hierarchy-add-tree hierarchy 'bird parentfn)
(should (equal (hierarchy-roots hierarchy) '(animal)))
(should (equal (hierarchy-children hierarchy 'animal) '(bird)))))
(ert-deftest hierarchy-add-item-and-its-parent ()
(let ((parentfn (lambda (item)
(cl-case item
(bird 'animal))))
(hierarchy (hierarchy-new)))
(hierarchy-add-tree hierarchy 'bird parentfn)
(hierarchy-add-tree hierarchy 'animal parentfn)
(should (equal (hierarchy-roots hierarchy) '(animal)))
(should (equal (hierarchy-children hierarchy 'animal) '(bird)))))
(ert-deftest hierarchy-add-item-and-its-child ()
(let ((parentfn (lambda (item)
(cl-case item
(bird 'animal))))
(hierarchy (hierarchy-new)))
(hierarchy-add-tree hierarchy 'animal parentfn)
(hierarchy-add-tree hierarchy 'bird parentfn)
(should (equal (hierarchy-roots hierarchy) '(animal)))
(should (equal (hierarchy-children hierarchy 'animal) '(bird)))))
(ert-deftest hierarchy-add-two-items-sharing-parent ()
(let ((parentfn (lambda (item)
(cl-case item
(dove 'bird)
(pigeon 'bird))))
(hierarchy (hierarchy-new)))
(hierarchy-add-tree hierarchy 'dove parentfn)
(hierarchy-add-tree hierarchy 'pigeon parentfn)
(should (equal (hierarchy-roots hierarchy) '(bird)))
(should (equal (hierarchy-children hierarchy 'bird) '(dove pigeon)))))
(ert-deftest hierarchy-add-two-hierarchies ()
(let ((parentfn (lambda (item)
(cl-case item
(dove 'bird)
(circle 'shape))))
(hierarchy (hierarchy-new)))
(hierarchy-add-tree hierarchy 'dove parentfn)
(hierarchy-add-tree hierarchy 'circle parentfn)
(should (equal (hierarchy-roots hierarchy) '(bird shape)))
(should (equal (hierarchy-children hierarchy 'bird) '(dove)))
(should (equal (hierarchy-children hierarchy 'shape) '(circle)))))
(ert-deftest hierarchy-add-with-childrenfn ()
(let ((childrenfn (lambda (item)
(cl-case item
(animal '(bird))
(bird '(dove pigeon)))))
(hierarchy (hierarchy-new)))
(hierarchy-add-tree hierarchy 'animal nil childrenfn)
(should (equal (hierarchy-roots hierarchy) '(animal)))
(should (equal (hierarchy-children hierarchy 'animal) '(bird)))
(should (equal (hierarchy-children hierarchy 'bird) '(dove pigeon)))))
(ert-deftest hierarchy-add-with-parentfn-and-childrenfn ()
(let ((parentfn (lambda (item)
(cl-case item
(bird 'animal)
(animal 'life-form))))
(childrenfn (lambda (item)
(cl-case item
(bird '(dove pigeon))
(pigeon '(ashy-wood-pigeon)))))
(hierarchy (hierarchy-new)))
(hierarchy-add-tree hierarchy 'bird parentfn childrenfn)
(should (equal (hierarchy-roots hierarchy) '(life-form)))
(should (equal (hierarchy-children hierarchy 'life-form) '(animal)))
(should (equal (hierarchy-children hierarchy 'animal) '(bird)))
(should (equal (hierarchy-children hierarchy 'bird) '(dove pigeon)))
(should (equal (hierarchy-children hierarchy 'pigeon) '(ashy-wood-pigeon)))))
(ert-deftest hierarchy-add-twice-with-parentfn-and-childrenfn ()
(let* ((parentfn (lambda (item)
(cl-case item
(dove 'bird)
(bird 'animal))))
(childrenfn (lambda (item)
(cl-case item
(animal '(bird))
(bird '(dove)))))
(hierarchy (hierarchy-new)))
(hierarchy-add-tree hierarchy 'bird parentfn childrenfn)
(should (equal (hierarchy-children hierarchy 'animal) '(bird)))
(should (equal (hierarchy-children hierarchy 'bird) '(dove)))))
(ert-deftest hierarchy-add-trees ()
(let ((parentfn (lambda (item)
(cl-case item
(dove 'bird)
(pigeon 'bird)
(bird 'animal))))
(hierarchy (hierarchy-new)))
(hierarchy-add-trees hierarchy '(dove pigeon) parentfn)
(should (equal (hierarchy-roots hierarchy) '(animal)))
(should (equal (hierarchy-children hierarchy 'animal) '(bird)))
(should (equal (hierarchy-children hierarchy 'bird) '(dove pigeon)))))
(ert-deftest hierarchy-from-list ()
(let ((hierarchy (hierarchy-from-list
'(animal (bird (dove)
(pigeon))
(cow)
(dolphin)))))
(hierarchy-sort hierarchy (lambda (item1 item2)
(string< (car item1)
(car item2))))
(should (equal (hierarchy-to-string hierarchy (lambda (item) (symbol-name (car item))))
"animal\n bird\n dove\n pigeon\n cow\n dolphin\n"))))
(ert-deftest hierarchy-from-list-with-duplicates ()
(let ((hierarchy (hierarchy-from-list
'(a (b) (b))
t)))
(hierarchy-sort hierarchy (lambda (item1 item2)
;; sort by ID
(< (car item1) (car item2))))
(should (equal (hierarchy-length hierarchy) 3))
(should (equal (hierarchy-to-string
hierarchy
(lambda (item)
(format "%s(%s)"
(cadr item)
(car item))))
"a(1)\n b(2)\n b(3)\n"))))
(ert-deftest hierarchy-from-list-with-childrenfn ()
(let ((hierarchy (hierarchy-from-list
"abc"
nil
(lambda (item)
(when (string= item "abc")
(split-string item "" t))))))
(hierarchy-sort hierarchy (lambda (item1 item2) (string< item1 item2)))
(should (equal (hierarchy-length hierarchy) 4))
(should (equal (hierarchy-to-string hierarchy)
"abc\n a\n b\n c\n"))))
(ert-deftest hierarchy-add-relation-check-error-when-different-parent ()
(let ((parentfn (lambda (item)
(cl-case item
(bird 'animal))))
(hierarchy (hierarchy-new)))
(hierarchy-add-tree hierarchy 'bird parentfn)
(should-error
(hierarchy--add-relation hierarchy 'bird 'cow #'identity))))
(ert-deftest hierarchy-empty-p-return-non-nil-for-empty ()
(should (hierarchy-empty-p (hierarchy-new))))
(ert-deftest hierarchy-empty-p-return-nil-for-non-empty ()
(should-not (hierarchy-empty-p (hierarchy-animals))))
(ert-deftest hierarchy-length-of-empty-is-0 ()
(should (equal (hierarchy-length (hierarchy-new)) 0)))
(ert-deftest hierarchy-length-of-non-empty-counts-items ()
(let ((parentfn (lambda (item)
(cl-case item
(bird 'animal)
(dove 'bird)
(pigeon 'bird))))
(hierarchy (hierarchy-new)))
(hierarchy-add-tree hierarchy 'dove parentfn)
(hierarchy-add-tree hierarchy 'pigeon parentfn)
(should (equal (hierarchy-length hierarchy) 4))))
(ert-deftest hierarchy-has-root ()
(let ((parentfn (lambda (item)
(cl-case item
(bird 'animal)
(dove 'bird)
(pigeon 'bird))))
(hierarchy (hierarchy-new)))
(should-not (hierarchy-has-root hierarchy 'animal))
(should-not (hierarchy-has-root hierarchy 'bird))
(hierarchy-add-tree hierarchy 'dove parentfn)
(hierarchy-add-tree hierarchy 'pigeon parentfn)
(should (hierarchy-has-root hierarchy 'animal))
(should-not (hierarchy-has-root hierarchy 'bird))))
(ert-deftest hierarchy-leafs ()
(let ((animals (hierarchy-animals)))
(should (equal (hierarchy-leafs animals)
'(dove pigeon dolphin cow)))))
(ert-deftest hierarchy-leafs-includes-lonely-roots ()
(let ((parentfn (lambda (_) nil))
(hierarchy (hierarchy-new)))
(hierarchy-add-tree hierarchy 'foo parentfn)
(should (equal (hierarchy-leafs hierarchy)
'(foo)))))
(ert-deftest hierarchy-leafs-of-node ()
(let ((animals (hierarchy-animals)))
(should (equal (hierarchy-leafs animals 'cow) '()))
(should (equal (hierarchy-leafs animals 'animal) '(dove pigeon dolphin cow)))
(should (equal (hierarchy-leafs animals 'bird) '(dove pigeon)))
(should (equal (hierarchy-leafs animals 'dove) '()))))
(ert-deftest hierarchy-child-p ()
(let ((animals (hierarchy-animals)))
(should (hierarchy-child-p animals 'dove 'bird))
(should (hierarchy-child-p animals 'bird 'animal))
(should (hierarchy-child-p animals 'cow 'animal))
(should-not (hierarchy-child-p animals 'cow 'bird))
(should-not (hierarchy-child-p animals 'bird 'cow))
(should-not (hierarchy-child-p animals 'animal 'dove))
(should-not (hierarchy-child-p animals 'animal 'bird))))
(ert-deftest hierarchy-descendant ()
(let ((animals (hierarchy-animals)))
(should (hierarchy-descendant-p animals 'dove 'animal))
(should (hierarchy-descendant-p animals 'dove 'bird))
(should (hierarchy-descendant-p animals 'bird 'animal))
(should (hierarchy-descendant-p animals 'cow 'animal))
(should-not (hierarchy-descendant-p animals 'cow 'bird))
(should-not (hierarchy-descendant-p animals 'bird 'cow))
(should-not (hierarchy-descendant-p animals 'animal 'dove))
(should-not (hierarchy-descendant-p animals 'animal 'bird))))
(ert-deftest hierarchy-descendant-if-not-same ()
(let ((animals (hierarchy-animals)))
(should-not (hierarchy-descendant-p animals 'cow 'cow))
(should-not (hierarchy-descendant-p animals 'dove 'dove))
(should-not (hierarchy-descendant-p animals 'bird 'bird))
(should-not (hierarchy-descendant-p animals 'animal 'animal))))
;; keywords supported: :test :key
(ert-deftest hierarchy--set-equal ()
(should (hierarchy--set-equal '(1 2 3) '(1 2 3)))
(should (hierarchy--set-equal '(1 2 3) '(3 2 1)))
(should (hierarchy--set-equal '(3 2 1) '(1 2 3)))
(should-not (hierarchy--set-equal '(2 3) '(3 2 1)))
(should-not (hierarchy--set-equal '(1 2 3) '(2 3)))
(should-not (hierarchy--set-equal '("1" "2") '("2" "1") :test #'eq))
(should (hierarchy--set-equal '("1" "2") '("2" "1") :test #'equal))
(should-not (hierarchy--set-equal '(1 2) '(-1 -2)))
(should (hierarchy--set-equal '(1 2) '(-1 -2) :key #'abs))
(should-not (hierarchy--set-equal '(("1" 1) ("2" 1)) '(("1" 2) ("2" 2))))
(should-not (hierarchy--set-equal '(("1" 1) ("2" 1)) '(("1" 2) ("2" 2)) :key #'car))
(should-not (hierarchy--set-equal '(("1" 1) ("2" 1)) '(("1" 2) ("2" 2)) :test #'equal))
(should (hierarchy--set-equal '(("1" 1) ("2" 1)) '(("1" 2) ("2" 2)) :key #'car :test #'equal)))
(ert-deftest hierarchy-equal-returns-true-for-same-hierarchy ()
(let ((animals (hierarchy-animals)))
(should (hierarchy-equal animals animals))
(should (hierarchy-equal (hierarchy-animals) animals))))
(ert-deftest hierarchy-equal-returns-true-for-hierarchy-copies ()
(let ((animals (hierarchy-animals)))
(should (hierarchy-equal animals (hierarchy-copy animals)))))
(ert-deftest hierarchy-map-item-on-leaf ()
(let* ((animals (hierarchy-animals))
(result (hierarchy-map-item (lambda (item indent) (cons item indent))
'cow
animals)))
(should (equal result '((cow . 0))))))
(ert-deftest hierarchy-map-item-on-leaf-with-indent ()
(let* ((animals (hierarchy-animals))
(result (hierarchy-map-item (lambda (item indent) (cons item indent))
'cow
animals
2)))
(should (equal result '((cow . 2))))))
(ert-deftest hierarchy-map-item-on-parent ()
(let* ((animals (hierarchy-animals))
(result (hierarchy-map-item (lambda (item indent) (cons item indent))
'bird
animals)))
(should (equal result '((bird . 0) (dove . 1) (pigeon . 1))))))
(ert-deftest hierarchy-map-item-on-grand-parent ()
(let* ((animals (hierarchy-animals))
(result (hierarchy-map-item (lambda (item indent) (cons item indent))
'animal
animals)))
(should (equal result '((animal . 0) (bird . 1) (dove . 2) (pigeon . 2)
(cow . 1) (dolphin . 1))))))
(ert-deftest hierarchy-map-conses ()
(let* ((animals (hierarchy-animals))
(result (hierarchy-map (lambda (item indent)
(cons item indent))
animals)))
(should (equal result '((animal . 0)
(bird . 1)
(dove . 2)
(pigeon . 2)
(cow . 1)
(dolphin . 1))))))
(ert-deftest hierarchy-map-tree ()
(let ((animals (hierarchy-animals)))
(should (equal (hierarchy-map-tree (lambda (item indent children)
(list item indent children))
animals)
'(animal
0
((bird 1 ((dove 2 nil) (pigeon 2 nil)))
(cow 1 nil)
(dolphin 1 nil)))))))
(ert-deftest hierarchy-map-hierarchy-keeps-hierarchy ()
(let* ((animals (hierarchy-animals))
(result (hierarchy-map-hierarchy (lambda (item _) (identity item))
animals)))
(should (hierarchy-equal animals result))))
(ert-deftest hierarchy-map-applies-function ()
(let* ((animals (hierarchy-animals))
(parentfn (lambda (item)
(cond
((equal item "bird") "animal")
((equal item "dove") "bird")
((equal item "pigeon") "bird")
((equal item "cow") "animal")
((equal item "dolphin") "animal"))))
(expected (hierarchy-new)))
(hierarchy-add-tree expected "dove" parentfn)
(hierarchy-add-tree expected "pigeon" parentfn)
(hierarchy-add-tree expected "cow" parentfn)
(hierarchy-add-tree expected "dolphin" parentfn)
(should (hierarchy-equal
(hierarchy-map-hierarchy (lambda (item _) (symbol-name item)) animals)
expected))))
(ert-deftest hierarchy-extract-tree ()
(let* ((animals (hierarchy-animals))
(birds (hierarchy-extract-tree animals 'bird)))
(hierarchy-sort birds)
(should (equal (hierarchy-roots birds) '(animal)))
(should (equal (hierarchy-children birds 'animal) '(bird)))
(should (equal (hierarchy-children birds 'bird) '(dove pigeon)))))
(ert-deftest hierarchy-extract-tree-nil-if-not-in-hierarchy ()
(let* ((animals (hierarchy-animals)))
(should-not (hierarchy-extract-tree animals 'foobar))))
(ert-deftest hierarchy-items-of-empty-hierarchy-is-empty ()
(should (seq-empty-p (hierarchy-items (hierarchy-new)))))
(ert-deftest hierarchy-items-returns-sequence-of-same-length ()
(let* ((animals (hierarchy-animals))
(result (hierarchy-items animals)))
(should (= (seq-length result) (hierarchy-length animals)))))
(ert-deftest hierarchy-items-return-all-elements-of-hierarchy ()
(let* ((animals (hierarchy-animals))
(result (hierarchy-items animals)))
(should (equal (seq-sort #'string< result) '(animal bird cow dolphin dove pigeon)))))
(ert-deftest hierarchy-labelfn-indent-no-indent-if-0 ()
(let* ((labelfn-base (lambda (_item _indent) (insert "foo")))
(labelfn (hierarchy-labelfn-indent labelfn-base)))
(should (equal
(with-temp-buffer
(funcall labelfn "bar" 0)
(buffer-substring (point-min) (point-max)))
"foo"))))
(ert-deftest hierarchy-labelfn-indent-three-times-if-3 ()
(let* ((labelfn-base (lambda (_item _indent) (insert "foo")))
(labelfn (hierarchy-labelfn-indent labelfn-base)))
(should (equal
(with-temp-buffer
(funcall labelfn "bar" 3)
(buffer-substring (point-min) (point-max)))
" foo"))))
(ert-deftest hierarchy-labelfn-indent-default-indent-string ()
(let* ((labelfn-base (lambda (_item _indent) (insert "foo")))
(labelfn (hierarchy-labelfn-indent labelfn-base)))
(should (equal
(with-temp-buffer
(funcall labelfn "bar" 1)
(buffer-substring (point-min) (point-max)))
" foo"))))
(ert-deftest hierarchy-labelfn-indent-custom-indent-string ()
(let* ((labelfn-base (lambda (_item _indent) (insert "foo")))
(labelfn (hierarchy-labelfn-indent labelfn-base "###"))
(content (with-temp-buffer
(funcall labelfn "bar" 1)
(buffer-substring (point-min) (point-max)))))
(should (equal content "###foo"))))
(ert-deftest hierarchy-labelfn-button-propertize ()
(let* ((labelfn-base (lambda (_item _indent) (insert "foo")))
(actionfn #'identity)
(labelfn (hierarchy-labelfn-button labelfn-base actionfn))
(properties (with-temp-buffer
(funcall labelfn "bar" 1)
(text-properties-at 1))))
(should (equal (car properties) 'action))))
(ert-deftest hierarchy-labelfn-button-execute-labelfn ()
(let* ((labelfn-base (lambda (_item _indent) (insert "foo")))
(actionfn #'identity)
(labelfn (hierarchy-labelfn-button labelfn-base actionfn))
(content (with-temp-buffer
(funcall labelfn "bar" 1)
(buffer-substring-no-properties (point-min) (point-max)))))
(should (equal content "foo"))))
(ert-deftest hierarchy-labelfn-button-if-does-not-button-unless-condition ()
(let ((labelfn-base (lambda (_item _indent) (insert "foo")))
(spy-count 0)
(condition (lambda (_item _indent) nil)))
(cl-letf (((symbol-function 'hierarchy-labelfn-button) (lambda (_labelfn _actionfn) (lambda (_item _indent) (cl-incf spy-count)))))
(funcall (hierarchy-labelfn-button-if labelfn-base condition #'identity) nil nil)
(should (equal spy-count 0)))))
(ert-deftest hierarchy-labelfn-button-if-does-button-when-condition ()
(let ((labelfn-base (lambda (_item _indent) (insert "foo")))
(spy-count 0)
(condition (lambda (_item _indent) t)))
(cl-letf (((symbol-function 'hierarchy-labelfn-button) (lambda (_labelfn _actionfn) (lambda (_item _indent) (cl-incf spy-count)))))
(funcall (hierarchy-labelfn-button-if labelfn-base condition #'identity) nil nil)
(should (equal spy-count 1)))))
(ert-deftest hierarchy-labelfn-to-string ()
(let ((labelfn (lambda (item _indent) (insert item))))
(should (equal (hierarchy-labelfn-to-string labelfn "foo" 1) "foo"))))
(ert-deftest hierarchy-print ()
(let* ((animals (hierarchy-animals))
(result (with-temp-buffer
(hierarchy-print animals)
(buffer-substring-no-properties (point-min) (point-max)))))
(should (equal result "animal\n bird\n dove\n pigeon\n cow\n dolphin\n"))))
(ert-deftest hierarchy-to-string ()
(let* ((animals (hierarchy-animals))
(result (hierarchy-to-string animals)))
(should (equal result "animal\n bird\n dove\n pigeon\n cow\n dolphin\n"))))
(ert-deftest hierarchy-tabulated-display ()
(let* ((animals (hierarchy-animals))
(labelfn (lambda (item _indent) (insert (symbol-name item))))
(contents (with-temp-buffer
(hierarchy-tabulated-display animals labelfn (current-buffer))
(buffer-substring-no-properties (point-min) (point-max)))))
(should (equal contents "animal\nbird\ndove\npigeon\ncow\ndolphin\n"))))
(ert-deftest hierarchy-sort-non-root-nodes ()
(let* ((animals (hierarchy-animals)))
(should (equal (hierarchy-roots animals) '(animal)))
(should (equal (hierarchy-children animals 'animal) '(bird cow dolphin)))
(should (equal (hierarchy-children animals 'bird) '(dove pigeon)))))
(ert-deftest hierarchy-sort-roots ()
(let* ((organisms (hierarchy-new))
(parentfn (lambda (item)
(cl-case item
(oak 'plant)
(bird 'animal)))))
(hierarchy-add-tree organisms 'oak parentfn)
(hierarchy-add-tree organisms 'bird parentfn)
(hierarchy-sort organisms)
(should (equal (hierarchy-roots organisms) '(animal plant)))))
(provide 'hierarchy-tests)
;;; hierarchy-tests.el ends here