aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorChristopher Genovese2016-12-20 17:41:56 +0900
committerTino Calancha2016-12-20 17:41:56 +0900
commit35aaa6b6aa9a2e7b42465603fb32355a009c510f (patch)
tree59e390dc4ab4b10398da125ce1d1e4f2c03b9570 /test
parentf8072cd5c16f855505f6a0ce6a6b30309735705d (diff)
downloademacs-35aaa6b6aa9a2e7b42465603fb32355a009c510f.tar.gz
emacs-35aaa6b6aa9a2e7b42465603fb32355a009c510f.zip
ibuffer: New filters and commands
Add several new filters and improve documentation. See discussion on: https://lists.gnu.org/archive/html/emacs-devel/2016-11/msg00399.html * lisp/ibuf-ext.el: Add paragraph to file commentary. (ibuffer-saved-filters, ibuffer-filtering-qualifiers) (ibuffer-filter-groups): Update doc string. (ibuffer-unary-operand): Add new function that transparently handles 'not' formats for compound filters. (ibuffer-included-in-filter-p): Handle 'not' fully; update doc string. (ibuffer-included-in-filter-p-1): Handle 'and' compound filters. (ibuffer-decompose-filter): Handle 'and' as well, and handle 'not' consistently with other uses. (ibuffer-and-filter): New defun analogous to 'ibuffer-or-filter'. (ibuffer--or-and-filter): New defun. (ibuffer-or-filter, ibuffer-and-filter): Use it. (ibuffer-format-qualifier): Handle 'and' filters as well. (ibuffer-filter-by-basename, ibuffer-filter-by-file-extension) (ibuffer-filter-by-directory, ibuffer-filter-by-starred-name) (ibuffer-filter-by-modified, ibuffer-filter-by-visiting-file): Add new pre-defined filters. (ibuffer-filter-chosen-by-completion): Add new interactive command for easily choosing a filter from the descriptions. * lisp/ibuffer.el (ibuffer-mode-map): Bind ibuffer-filter-by-basename, ibuffer-filter-by-file-extension, ibuffer-filter-by-starred-name, ibuffer-filter-by-modified, ibuffer-filter-by-visiting-file to '/b', '/.', '/*', '/i', '/v' respectively; bind 'ibuffer-or-filter', 'ibuffer-and-filter', 'ibuffer-pop-filter' ,'ibuffer-pop-filter-group' and 'ibuffer-filter-disable' to '/|', '/&', '/<up>', '/S-<up>' and '/ DEL' respectively. * test/lisp/ibuffer-tests.el (ibuffer-autoload): Add appropriate skip specification. Add menu entries for the new filters. (ibuffer-filter-inclusion-1, ibuffer-filter-inclusion-2 ibuffer-filter-inclusion-3, ibuffer-filter-inclusion-4 ibuffer-filter-inclusion-5, ibuffer-filter-inclusion-6 ibuffer-filter-inclusion-7, ibuffer-filter-inclusion-8 ibuffer-decompose-filter, ibuffer-and-filter ibuffer-or-filter): Add new tests; they are skipped unless ibuf-ext is loaded. ; * etc/NEWS: Add entries for new user-facing features.
Diffstat (limited to 'test')
-rw-r--r--test/lisp/ibuffer-tests.el667
1 files changed, 666 insertions, 1 deletions
diff --git a/test/lisp/ibuffer-tests.el b/test/lisp/ibuffer-tests.el
index 92ed101e6bf..40760abd96a 100644
--- a/test/lisp/ibuffer-tests.el
+++ b/test/lisp/ibuffer-tests.el
@@ -24,7 +24,8 @@
24 (require 'ibuf-macs)) 24 (require 'ibuf-macs))
25 25
26(ert-deftest ibuffer-autoload () 26(ert-deftest ibuffer-autoload ()
27 "Tests to see whether reftex-auc has been autoloaded" 27 "Tests to see whether ibuffer has been autoloaded"
28 (skip-unless (not (featurep 'ibuf-ext)))
28 (should 29 (should
29 (fboundp 'ibuffer-mark-unsaved-buffers)) 30 (fboundp 'ibuffer-mark-unsaved-buffers))
30 (should 31 (should
@@ -138,5 +139,669 @@
138 (should-not ibuffer-filtering-qualifiers)) 139 (should-not ibuffer-filtering-qualifiers))
139 (setq ibuffer-filtering-qualifiers filters)))) 140 (setq ibuffer-filtering-qualifiers filters))))
140 141
142;; Test Filter Inclusion
143(let* (test-buffer-list ; accumulated buffers to clean up
144 ;; Utility functions without polluting the environment
145 (set-buffer-mode
146 (lambda (buffer mode)
147 "Set BUFFER's major mode to MODE, a mode function, or fundamental."
148 (with-current-buffer buffer
149 (funcall (or mode #'fundamental-mode)))))
150 (set-buffer-contents
151 (lambda (buffer size include-content)
152 "Add exactly SIZE bytes to BUFFER, including INCLUDE-CONTENT."
153 (when (or size include-content)
154 (let* ((unit "\n")
155 (chunk "ccccccccccccccccccccccccccccccc\n")
156 (chunk-size (length chunk))
157 (size (if (and size include-content (stringp include-content))
158 (- size (length include-content))
159 size)))
160 (unless (or (null size) (> size 0))
161 (error "size argument must be nil or positive"))
162 (with-current-buffer buffer
163 (when include-content
164 (insert include-content))
165 (when size
166 (dotimes (_ (floor size chunk-size))
167 (insert chunk))
168 (dotimes (_ (mod size chunk-size))
169 (insert unit)))
170 ;; prevent query on cleanup
171 (set-buffer-modified-p nil))))))
172 (create-file-buffer
173 (lambda (prefix &rest args-plist)
174 "Create a file and buffer with designated properties.
175 PREFIX is a string giving the beginning of the name, and ARGS-PLIST
176 is a series of keyword-value pairs, with allowed keywords
177 :suffix STRING, :size NUMBER, :mode MODE-FUNC, :include-content STRING.
178 Returns the created buffer."
179 (let* ((suffix (plist-get args-plist :suffix))
180 (size (plist-get args-plist :size))
181 (include (plist-get args-plist :include-content))
182 (mode (plist-get args-plist :mode))
183 (file (make-temp-file prefix nil suffix))
184 (buf (find-file-noselect file t)))
185 (push buf test-buffer-list) ; record for cleanup
186 (funcall set-buffer-mode buf mode)
187 (funcall set-buffer-contents buf size include)
188 buf)))
189 (create-non-file-buffer
190 (lambda (prefix &rest args-plist)
191 "Create a non-file and buffer with designated properties.
192 PREFIX is a string giving the beginning of the name, and ARGS-PLIST
193 is a series of keyword-value pairs, with allowed keywords
194 :size NUMBER, :mode MODE-FUNC, :include-content STRING.
195 Returns the created buffer."
196 (let* ((size (plist-get args-plist :size))
197 (include (plist-get args-plist :include-content))
198 (mode (plist-get args-plist :mode))
199 (buf (generate-new-buffer prefix)))
200 (push buf test-buffer-list) ; record for cleanup
201 (funcall set-buffer-mode buf mode)
202 (funcall set-buffer-contents buf size include)
203 buf)))
204 (clean-up
205 (lambda ()
206 "Restore all emacs state modified during the tests"
207 (while test-buffer-list ; created temporary buffers
208 (let ((buf (pop test-buffer-list)))
209 (with-current-buffer buf (bury-buffer)) ; ensure not selected
210 (kill-buffer buf))))))
211 ;; Tests
212 (ert-deftest ibuffer-filter-inclusion-1 ()
213 "Tests inclusion using basic filter combinators with a single buffer."
214 (skip-unless (featurep 'ibuf-ext))
215 (unwind-protect
216 (let ((buf
217 (funcall create-file-buffer "ibuf-test-1" :size 100
218 :include-content "One ring to rule them all\n")))
219 (should (ibuffer-included-in-filters-p buf '((size-gt . 99))))
220 (should (ibuffer-included-in-filters-p buf '((size-lt . 101))))
221 (should (ibuffer-included-in-filters-p
222 buf '((mode . fundamental-mode))))
223 (should (ibuffer-included-in-filters-p
224 buf '((content . "ring to rule them all"))))
225 (should (ibuffer-included-in-filters-p
226 buf '((and (content . "ring to rule them all")))))
227 (should (ibuffer-included-in-filters-p
228 buf '((and (and (content . "ring to rule them all"))))))
229 (should (ibuffer-included-in-filters-p
230 buf '((and (and (and (content . "ring to rule them all")))))))
231 (should (ibuffer-included-in-filters-p
232 buf '((or (content . "ring to rule them all")))))
233 (should (ibuffer-included-in-filters-p
234 buf '((not (not (content . "ring to rule them all"))))))
235 (should (ibuffer-included-in-filters-p
236 buf '((and (size-gt . 99)
237 (content . "ring to rule them all")
238 (mode . fundamental-mode)
239 (basename . "\\`ibuf-test-1")))))
240 (should (ibuffer-included-in-filters-p
241 buf '((not (or (not (size-gt . 99))
242 (not (content . "ring to rule them all"))
243 (not (mode . fundamental-mode))
244 (not (basename . "\\`ibuf-test-1")))))))
245 (should (ibuffer-included-in-filters-p
246 buf '((and (or (size-gt . 99) (size-lt . 10))
247 (and (content . "ring.*all")
248 (content . "rule")
249 (content . "them all")
250 (content . "One"))
251 (not (mode . text-mode))
252 (basename . "\\`ibuf-test-1"))))))
253 (funcall clean-up)))
254
255 (ert-deftest ibuffer-filter-inclusion-2 ()
256 "Tests inclusion of basic filters in combination on a single buffer."
257 (skip-unless (featurep 'ibuf-ext))
258 (unwind-protect
259 (let ((buf
260 (funcall create-file-buffer "ibuf-test-2" :size 200
261 :mode #'text-mode
262 :include-content "and in the darkness find them\n")))
263 (should (ibuffer-included-in-filters-p buf '((size-gt . 199))))
264 (should (ibuffer-included-in-filters-p buf '((size-lt . 201))))
265 (should (ibuffer-included-in-filters-p buf '((not size-gt . 200))))
266 (should (ibuffer-included-in-filters-p buf '((not (size-gt . 200)))))
267 (should (ibuffer-included-in-filters-p
268 buf '((and (size-gt . 199) (size-lt . 201)))))
269 (should (ibuffer-included-in-filters-p
270 buf '((or (size-gt . 199) (size-gt . 201)))))
271 (should (ibuffer-included-in-filters-p
272 buf '((or (size-gt . 201) (size-gt . 199)))))
273 (should (ibuffer-included-in-filters-p
274 buf '((size-gt . 199) (mode . text-mode)
275 (content . "darkness find them"))))
276 (should (ibuffer-included-in-filters-p
277 buf '((and (size-gt . 199) (mode . text-mode)
278 (content . "darkness find them")))))
279 (should (ibuffer-included-in-filters-p
280 buf '((not (or (not (size-gt . 199)) (not (mode . text-mode))
281 (not (content . "darkness find them")))))))
282 (should (ibuffer-included-in-filters-p
283 buf '((or (size-gt . 200) (content . "darkness find them")
284 (derived-mode . emacs-lisp-mode)))))
285 (should-not (ibuffer-included-in-filters-p
286 buf '((or (size-gt . 200) (content . "rule them all")
287 (derived-mode . emacs-lisp-mode))))))
288 (funcall clean-up)))
289
290 (ert-deftest ibuffer-filter-inclusion-3 ()
291 "Tests inclusion with filename filters on specified buffers."
292 (skip-unless (featurep 'ibuf-ext))
293 (unwind-protect
294 (let* ((bufA
295 (funcall create-file-buffer "ibuf-test-3.a" :size 50
296 :mode #'text-mode
297 :include-content "...but a multitude of drops?\n"))
298 (bufB
299 (funcall create-non-file-buffer "ibuf-test-3.b" :size 50
300 :mode #'text-mode
301 :include-content "...but a multitude of drops?\n"))
302 (dirA (with-current-buffer bufA default-directory))
303 (dirB (with-current-buffer bufB default-directory)))
304 (should (ibuffer-included-in-filters-p
305 bufA '((basename . "ibuf-test-3"))))
306 (should (ibuffer-included-in-filters-p
307 bufA '((basename . "test-3\\.a"))))
308 (should (ibuffer-included-in-filters-p
309 bufA '((file-extension . "a"))))
310 (should (ibuffer-included-in-filters-p
311 bufA (list (cons 'directory dirA))))
312 (should-not (ibuffer-included-in-filters-p
313 bufB '((basename . "ibuf-test-3"))))
314 (should-not (ibuffer-included-in-filters-p
315 bufB '((file-extension . "b"))))
316 (should (ibuffer-included-in-filters-p
317 bufB (list (cons 'directory dirB))))
318 (should (ibuffer-included-in-filters-p
319 bufA '((name . "ibuf-test-3"))))
320 (should (ibuffer-included-in-filters-p
321 bufB '((name . "ibuf-test-3")))))
322 (funcall clean-up)))
323
324 (ert-deftest ibuffer-filter-inclusion-4 ()
325 "Tests inclusion with various filters on a single buffer."
326 (skip-unless (featurep 'ibuf-ext))
327 (unwind-protect
328 (let ((buf
329 (funcall create-file-buffer "ibuf-test-4"
330 :mode #'emacs-lisp-mode :suffix ".el"
331 :include-content "(message \"--%s--\" 'emacs-rocks)\n")))
332 (should (ibuffer-included-in-filters-p
333 buf '((file-extension . "el"))))
334 (should (ibuffer-included-in-filters-p
335 buf '((derived-mode . prog-mode))))
336 (should (ibuffer-included-in-filters-p
337 buf '((used-mode . emacs-lisp-mode))))
338 (should (ibuffer-included-in-filters-p
339 buf '((mode . emacs-lisp-mode))))
340 (with-current-buffer buf (set-buffer-modified-p t))
341 (should (ibuffer-included-in-filters-p buf '((modified))))
342 (with-current-buffer buf (set-buffer-modified-p nil))
343 (should (ibuffer-included-in-filters-p buf '((not modified))))
344 (should (ibuffer-included-in-filters-p
345 buf '((and (file-extension . "el")
346 (derived-mode . prog-mode)
347 (not modified)))))
348 (should (ibuffer-included-in-filters-p
349 buf '((or (file-extension . "tex")
350 (derived-mode . prog-mode)
351 (modified)))))
352 (should (ibuffer-included-in-filters-p
353 buf '((file-extension . "el")
354 (derived-mode . prog-mode)
355 (not modified)))))
356 (funcall clean-up)))
357
358 (ert-deftest ibuffer-filter-inclusion-5 ()
359 "Tests inclusion with various filters on a single buffer."
360 (skip-unless (featurep 'ibuf-ext))
361 (unwind-protect
362 (let ((buf
363 (funcall create-non-file-buffer "ibuf-test-5.el"
364 :mode #'emacs-lisp-mode
365 :include-content
366 "(message \"--%s--\" \"It really does!\")\n")))
367 (should-not (ibuffer-included-in-filters-p
368 buf '((file-extension . "el"))))
369 (should (ibuffer-included-in-filters-p
370 buf '((size-gt . 18))))
371 (should (ibuffer-included-in-filters-p
372 buf '((predicate . (lambda ()
373 (> (- (point-max) (point-min)) 18))))))
374 (should (ibuffer-included-in-filters-p
375 buf '((and (mode . emacs-lisp-mode)
376 (or (starred-name)
377 (size-gt . 18))
378 (and (not (size-gt . 100))
379 (content . "[Ii]t *really does!")
380 (or (name . "test-5")
381 (not (filename . "test-5")))))))))
382 (funcall clean-up)))
383
384 (ert-deftest ibuffer-filter-inclusion-6 ()
385 "Tests inclusion using saved filters and DeMorgan's laws."
386 (skip-unless (featurep 'ibuf-ext))
387 (unwind-protect
388 (let ((buf
389 (funcall create-non-file-buffer "*ibuf-test-6*" :size 65
390 :mode #'text-mode))
391 (buf2
392 (funcall create-file-buffer "ibuf-test-6a" :suffix ".html"
393 :mode #'html-mode
394 :include-content
395 "<HTML><BODY><H1>Hello, World!</H1></BODY></HTML>")))
396 (should (ibuffer-included-in-filters-p buf '((starred-name))))
397 (should-not (ibuffer-included-in-filters-p
398 buf '((saved . "text document"))))
399 (should (ibuffer-included-in-filters-p buf2 '((saved . "web"))))
400 (should (ibuffer-included-in-filters-p
401 buf2 '((not (and (not (derived-mode . sgml-mode))
402 (not (derived-mode . css-mode))
403 (not (mode . javascript-mode))
404 (not (mode . js2-mode))
405 (not (mode . scss-mode))
406 (not (derived-mode . haml-mode))
407 (not (mode . sass-mode)))))))
408 (should (ibuffer-included-in-filters-p
409 buf '((and (starred-name)
410 (or (size-gt . 50) (filename . "foo"))))))
411 (should (ibuffer-included-in-filters-p
412 buf '((not (or (not starred-name)
413 (and (size-lt . 51)
414 (not (filename . "foo")))))))))
415 (funcall clean-up)))
416
417 (ert-deftest ibuffer-filter-inclusion-7 ()
418 "Tests inclusion with various filters on a single buffer."
419 (skip-unless (featurep 'ibuf-ext))
420 (unwind-protect
421 (let ((buf
422 (funcall create-non-file-buffer "ibuf-test-7"
423 :mode #'artist-mode)))
424 (should (ibuffer-included-in-filters-p
425 buf '((not (starred-name)))))
426 (should (ibuffer-included-in-filters-p
427 buf '((not starred-name))))
428 (should (ibuffer-included-in-filters-p
429 buf '((not (not (not starred-name))))))
430 (should (ibuffer-included-in-filters-p
431 buf '((not (modified)))))
432 (should (ibuffer-included-in-filters-p
433 buf '((not modified))))
434 (should (ibuffer-included-in-filters-p
435 buf '((not (not (not modified)))))))
436 (funcall clean-up)))
437
438 (ert-deftest ibuffer-filter-inclusion-8 ()
439 "Tests inclusion with various filters."
440 (skip-unless (featurep 'ibuf-ext))
441 (unwind-protect
442 (let ((bufA
443 (funcall create-non-file-buffer "ibuf-test-8a"
444 :mode #'artist-mode))
445 (bufB (funcall create-non-file-buffer "*ibuf-test-8b*" :size 32))
446 (bufC (funcall create-file-buffer "ibuf-test8c" :suffix "*"
447 :size 64))
448 (bufD (funcall create-file-buffer "*ibuf-test8d" :size 128))
449 (bufE (funcall create-file-buffer "*ibuf-test8e" :suffix "*<2>"
450 :size 16))
451 (bufF (and (funcall create-non-file-buffer "*ibuf-test8f*")
452 (funcall create-non-file-buffer "*ibuf-test8f*"
453 :size 8))))
454 (with-current-buffer bufA (set-buffer-modified-p t))
455 (should (ibuffer-included-in-filters-p
456 bufA '((and (not starred-name)
457 (modified)
458 (name . "test-8")
459 (not (size-gt . 100))
460 (mode . picture-mode)))))
461 (with-current-buffer bufA (set-buffer-modified-p nil))
462 (should-not (ibuffer-included-in-filters-p
463 bufA '((or (starred-name) (visiting-file) (modified)))))
464 (should (ibuffer-included-in-filters-p
465 bufB '((and (starred-name)
466 (name . "test.*8b")
467 (size-gt . 31)
468 (not visiting-file)))))
469 (should (ibuffer-included-in-filters-p
470 bufC '((and (not (starred-name))
471 (visiting-file)
472 (name . "8c[^*]*\\*")
473 (size-lt . 65)))))
474 (should (ibuffer-included-in-filters-p
475 bufD '((and (not (starred-name))
476 (visiting-file)
477 (name . "\\`\\*.*test8d")
478 (size-lt . 129)
479 (size-gt . 127)))))
480 (should (ibuffer-included-in-filters-p
481 bufE '((and (starred-name)
482 (visiting-file)
483 (name . "8e.*?\\*<[[:digit:]]+>")
484 (size-gt . 10)))))
485 (should (ibuffer-included-in-filters-p
486 bufF '((and (starred-name)
487 (not (visiting-file))
488 (name . "8f\\*<[[:digit:]]>")
489 (size-lt . 10))))))
490 (funcall clean-up))))
491
492;; Test Filter Combination and Decomposition
493(let* (ibuffer-to-kill ; if non-nil, kill this buffer at cleanup
494 (ibuffer-already 'check) ; existing ibuffer buffer to use but not kill
495 ;; Utility functions without polluting the environment
496 (get-test-ibuffer
497 (lambda ()
498 "Returns a test ibuffer-mode buffer, creating one if necessary.
499 If a new buffer is created, it is named \"*Test-Ibuffer*\" and is
500 saved to `ibuffer-to-kill' for later cleanup."
501 (when (eq ibuffer-already 'check)
502 (setq ibuffer-already
503 (catch 'found-buf
504 (dolist (buf (buffer-list) nil)
505 (when (with-current-buffer buf
506 (derived-mode-p 'ibuffer-mode))
507 (throw 'found-buf buf))))))
508 (or ibuffer-already
509 ibuffer-to-kill
510 (let ((test-ibuf-name "*Test-Ibuffer*"))
511 (ibuffer nil test-ibuf-name nil t)
512 (setq ibuffer-to-kill (get-buffer test-ibuf-name))))))
513 (clean-up
514 (lambda ()
515 "Restore all emacs state modified during the tests"
516 (when ibuffer-to-kill ; created ibuffer
517 (with-current-buffer ibuffer-to-kill
518 (set-buffer-modified-p nil)
519 (bury-buffer))
520 (kill-buffer ibuffer-to-kill)
521 (setq ibuffer-to-kill nil))
522 (when (and ibuffer-already (not (eq ibuffer-already 'check)))
523 ;; restore existing ibuffer state
524 (ibuffer-update nil t)))))
525 ;; Tests
526 (ert-deftest ibuffer-decompose-filter ()
527 "Tests `ibuffer-decompose-filter' for and, or, not, and saved."
528 (skip-unless (featurep 'ibuf-ext))
529 (unwind-protect
530 (let ((ibuf (funcall get-test-ibuffer)))
531 (with-current-buffer ibuf
532 (let ((ibuffer-filtering-qualifiers nil)
533 (ibuffer-filter-groups nil)
534 (filters '((size-gt . 100) (not (starred-name))
535 (name . "foo"))))
536 (progn
537 (push (cons 'or filters) ibuffer-filtering-qualifiers)
538 (ibuffer-decompose-filter)
539 (should (equal filters ibuffer-filtering-qualifiers))
540 (setq ibuffer-filtering-qualifiers nil))
541 (progn
542 (push (cons 'and filters) ibuffer-filtering-qualifiers)
543 (ibuffer-decompose-filter)
544 (should (equal filters ibuffer-filtering-qualifiers))
545 (setq ibuffer-filtering-qualifiers nil))
546 (progn
547 (push (list 'not (car filters)) ibuffer-filtering-qualifiers)
548 (ibuffer-decompose-filter)
549 (should (equal (list (car filters))
550 ibuffer-filtering-qualifiers))
551 (setq ibuffer-filtering-qualifiers nil))
552 (progn
553 (push (cons 'not (car filters)) ibuffer-filtering-qualifiers)
554 (ibuffer-decompose-filter)
555 (should (equal (list (car filters))
556 ibuffer-filtering-qualifiers))
557 (setq ibuffer-filtering-qualifiers nil))
558 (let ((gnus (assoc "gnus" ibuffer-saved-filters)))
559 (push '(saved . "gnus") ibuffer-filtering-qualifiers)
560 (ibuffer-decompose-filter)
561 (should (equal (cdr gnus) ibuffer-filtering-qualifiers))
562 (ibuffer-decompose-filter)
563 (should (equal (cdr (cadr gnus)) ibuffer-filtering-qualifiers))
564 (setq ibuffer-filtering-qualifiers nil))
565 (when (not (assoc "__unknown__" ibuffer-saved-filters))
566 (push '(saved . "__uknown__") ibuffer-filtering-qualifiers)
567 (should-error (ibuffer-decompose-filter) :type 'error)
568 (setq ibuffer-filtering-qualifiers nil))
569 (progn
570 (push (car filters) ibuffer-filtering-qualifiers)
571 (should-error (ibuffer-decompose-filter) :type 'error)
572 (setq ibuffer-filtering-qualifiers nil)))))
573 (funcall clean-up)))
574
575 (ert-deftest ibuffer-and-filter ()
576 "Tests `ibuffer-and-filter' in an Ibuffer buffer."
577 (skip-unless (featurep 'ibuf-ext))
578 (unwind-protect
579 (let ((ibuf (funcall get-test-ibuffer)))
580 (with-current-buffer ibuf
581 (let ((ibuffer-filtering-qualifiers nil)
582 (ibuffer-filter-groups nil)
583 (filters [(size-gt . 100) (not (starred-name))
584 (filename . "A") (mode . text-mode)]))
585 (should-error (ibuffer-and-filter) :type 'error)
586 (progn
587 (push (aref filters 1) ibuffer-filtering-qualifiers)
588 (should-error (ibuffer-and-filter) :type 'error))
589 (should (progn
590 (push (aref filters 0) ibuffer-filtering-qualifiers)
591 (ibuffer-and-filter)
592 (and (equal (list 'and (aref filters 0) (aref filters 1))
593 (car ibuffer-filtering-qualifiers))
594 (null (cdr ibuffer-filtering-qualifiers)))))
595 (should (progn
596 (ibuffer-and-filter 'decompose)
597 (and (equal (aref filters 0)
598 (pop ibuffer-filtering-qualifiers))
599 (equal (aref filters 1)
600 (pop ibuffer-filtering-qualifiers))
601 (null ibuffer-filtering-qualifiers))))
602 (should (progn
603 (push (list 'and (aref filters 2) (aref filters 3))
604 ibuffer-filtering-qualifiers)
605 (push (list 'and (aref filters 0) (aref filters 1))
606 ibuffer-filtering-qualifiers)
607 (ibuffer-and-filter)
608 (and (equal (list 'and (aref filters 0) (aref filters 1)
609 (aref filters 2) (aref filters 3))
610 (car ibuffer-filtering-qualifiers))
611 (null (cdr ibuffer-filtering-qualifiers)))))
612 (pop ibuffer-filtering-qualifiers)
613 (should (progn
614 (push (list 'or (aref filters 2) (aref filters 3))
615 ibuffer-filtering-qualifiers)
616 (push (list 'and (aref filters 0) (aref filters 1))
617 ibuffer-filtering-qualifiers)
618 (ibuffer-and-filter)
619 (and (equal (list 'and (aref filters 0) (aref filters 1)
620 (list 'or (aref filters 2)
621 (aref filters 3)))
622 (car ibuffer-filtering-qualifiers))
623 (null (cdr ibuffer-filtering-qualifiers)))))
624 (pop ibuffer-filtering-qualifiers)
625 (should (progn
626 (push (list 'and (aref filters 2) (aref filters 3))
627 ibuffer-filtering-qualifiers)
628 (push (list 'or (aref filters 0) (aref filters 1))
629 ibuffer-filtering-qualifiers)
630 (ibuffer-and-filter)
631 (and (equal (list 'and (list 'or (aref filters 0)
632 (aref filters 1))
633 (aref filters 2) (aref filters 3))
634 (car ibuffer-filtering-qualifiers))
635 (null (cdr ibuffer-filtering-qualifiers)))))
636 (pop ibuffer-filtering-qualifiers)
637 (should (progn
638 (push (list 'or (aref filters 2) (aref filters 3))
639 ibuffer-filtering-qualifiers)
640 (push (list 'or (aref filters 0) (aref filters 1))
641 ibuffer-filtering-qualifiers)
642 (ibuffer-and-filter)
643 (and (equal (list 'and
644 (list 'or (aref filters 0)
645 (aref filters 1))
646 (list 'or (aref filters 2)
647 (aref filters 3)))
648 (car ibuffer-filtering-qualifiers))
649 (null (cdr ibuffer-filtering-qualifiers))))))))
650 (funcall clean-up)))
651
652 (ert-deftest ibuffer-or-filter ()
653 "Tests `ibuffer-or-filter' in an Ibuffer buffer."
654 (skip-unless (featurep 'ibuf-ext))
655 (unwind-protect
656 (let ((ibuf (funcall get-test-ibuffer)))
657 (with-current-buffer ibuf
658 (let ((ibuffer-filtering-qualifiers nil)
659 (ibuffer-filter-groups nil)
660 (filters [(size-gt . 100) (not (starred-name))
661 (filename . "A") (mode . text-mode)]))
662 (should-error (ibuffer-or-filter) :type 'error)
663 (progn
664 (push (aref filters 1) ibuffer-filtering-qualifiers)
665 (should-error (ibuffer-or-filter) :type 'error))
666 (should (progn
667 (push (aref filters 0) ibuffer-filtering-qualifiers)
668 (ibuffer-or-filter)
669 (and (equal (list 'or (aref filters 0) (aref filters 1))
670 (car ibuffer-filtering-qualifiers))
671 (null (cdr ibuffer-filtering-qualifiers)))))
672 (should (progn
673 (ibuffer-or-filter 'decompose)
674 (and (equal (aref filters 0)
675 (pop ibuffer-filtering-qualifiers))
676 (equal (aref filters 1)
677 (pop ibuffer-filtering-qualifiers))
678 (null ibuffer-filtering-qualifiers))))
679 (should (progn
680 (push (list 'or (aref filters 2) (aref filters 3))
681 ibuffer-filtering-qualifiers)
682 (push (list 'or (aref filters 0) (aref filters 1))
683 ibuffer-filtering-qualifiers)
684 (ibuffer-or-filter)
685 (and (equal (list 'or (aref filters 0) (aref filters 1)
686 (aref filters 2) (aref filters 3))
687 (car ibuffer-filtering-qualifiers))
688 (null (cdr ibuffer-filtering-qualifiers)))))
689 (pop ibuffer-filtering-qualifiers)
690 (should (progn
691 (push (list 'and (aref filters 2) (aref filters 3))
692 ibuffer-filtering-qualifiers)
693 (push (list 'or (aref filters 0) (aref filters 1))
694 ibuffer-filtering-qualifiers)
695 (ibuffer-or-filter)
696 (and (equal (list 'or (aref filters 0) (aref filters 1)
697 (list 'and (aref filters 2)
698 (aref filters 3)))
699 (car ibuffer-filtering-qualifiers))
700 (null (cdr ibuffer-filtering-qualifiers)))))
701 (pop ibuffer-filtering-qualifiers)
702 (should (progn
703 (push (list 'or (aref filters 2) (aref filters 3))
704 ibuffer-filtering-qualifiers)
705 (push (list 'and (aref filters 0) (aref filters 1))
706 ibuffer-filtering-qualifiers)
707 (ibuffer-or-filter)
708 (and (equal (list 'or (list 'and (aref filters 0)
709 (aref filters 1))
710 (aref filters 2) (aref filters 3))
711 (car ibuffer-filtering-qualifiers))
712 (null (cdr ibuffer-filtering-qualifiers)))))
713 (pop ibuffer-filtering-qualifiers)
714 (should (progn
715 (push (list 'and (aref filters 2) (aref filters 3))
716 ibuffer-filtering-qualifiers)
717 (push (list 'and (aref filters 0) (aref filters 1))
718 ibuffer-filtering-qualifiers)
719 (ibuffer-or-filter)
720 (and (equal (list 'or
721 (list 'and (aref filters 0)
722 (aref filters 1))
723 (list 'and (aref filters 2)
724 (aref filters 3)))
725 (car ibuffer-filtering-qualifiers))
726 (null (cdr ibuffer-filtering-qualifiers))))))))
727 (funcall clean-up))))
728
729(ert-deftest ibuffer-format-qualifier ()
730 "Tests string recommendation of filter from `ibuffer-format-qualifier'."
731 (skip-unless (featurep 'ibuf-ext))
732 (let ((test1 '(mode . org-mode))
733 (test2 '(size-lt . 100))
734 (test3 '(derived-mode . prog-mode))
735 (test4 '(or (size-gt . 10000)
736 (and (not (starred-name))
737 (directory . "\\<org\\>"))))
738 (test5 '(or (filename . "scratch")
739 (filename . "bonz")
740 (filename . "temp")))
741 (test6 '(or (mode . emacs-lisp-mode) (file-extension . "elc?")
742 (and (starred-name) (name . "elisp"))
743 (mode . lisp-interaction-mode)))
744 (description (lambda (q)
745 (cadr (assq q ibuffer-filtering-alist))))
746 (tag (lambda (&rest args )
747 (concat " [" (apply #'concat args) "]"))))
748 (should (equal (ibuffer-format-qualifier test1)
749 (funcall tag (funcall description 'mode)
750 ": " "org-mode")))
751 (should (equal (ibuffer-format-qualifier test2)
752 (funcall tag (funcall description 'size-lt)
753 ": " "100")))
754 (should (equal (ibuffer-format-qualifier test3)
755 (funcall tag (funcall description 'derived-mode)
756 ": " "prog-mode")))
757 (should (equal (ibuffer-format-qualifier test4)
758 (funcall tag "OR"
759 (funcall tag (funcall description 'size-gt)
760 ": " (format "%s" 10000))
761 (funcall tag "AND"
762 (funcall tag "NOT"
763 (funcall tag
764 (funcall description
765 'starred-name)
766 ": " "nil"))
767 (funcall tag
768 (funcall description 'directory)
769 ": " "\\<org\\>")))))
770 (should (equal (ibuffer-format-qualifier test5)
771 (funcall tag "OR"
772 (funcall tag (funcall description 'filename)
773 ": " "scratch")
774 (funcall tag (funcall description 'filename)
775 ": " "bonz")
776 (funcall tag (funcall description 'filename)
777 ": " "temp"))))
778 (should (equal (ibuffer-format-qualifier test6)
779 (funcall tag "OR"
780 (funcall tag (funcall description 'mode)
781 ": " "emacs-lisp-mode")
782 (funcall tag (funcall description 'file-extension)
783 ": " "elc?")
784 (funcall tag "AND"
785 (funcall tag
786 (funcall description 'starred-name)
787 ": " "nil")
788 (funcall tag
789 (funcall description 'name)
790 ": " "elisp"))
791 (funcall tag (funcall description 'mode)
792 ": " "lisp-interaction-mode"))))))
793
794(ert-deftest ibuffer-unary-operand ()
795 "Tests `ibuffer-unary-operand': (not cell) or (not . cell) -> cell."
796 (skip-unless (featurep 'ibuf-ext))
797 (should (equal (ibuffer-unary-operand '(not . (mode "foo")))
798 '(mode "foo")))
799 (should (equal (ibuffer-unary-operand '(not (mode "foo")))
800 '(mode "foo")))
801 (should (equal (ibuffer-unary-operand '(not "cdr"))
802 '("cdr")))
803 (should (equal (ibuffer-unary-operand '(not)) nil))
804 (should (equal (ibuffer-unary-operand '(not . a)) 'a)))
805
141(provide 'ibuffer-tests) 806(provide 'ibuffer-tests)
142;; ibuffer-tests.el ends here 807;; ibuffer-tests.el ends here