1 ;;; stream-tests.el --- Unit tests for stream.el -*- lexical-binding: t -*-
3 ;; Copyright (C) 2015 Free Software Foundation, Inc.
5 ;; Author: Nicolas Petton <nicolas@petton.fr>
7 ;; Maintainer: emacs-devel@gnu.org
9 ;; This file is part of GNU Emacs.
11 ;; GNU Emacs is free software: you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation, either version 3 of the License, or
14 ;; (at your option) any later version.
16 ;; GNU Emacs is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
31 (defun stream-to-list (stream)
32 "Eagerly traverse STREAM and return a list of its elements."
39 (ert-deftest stream-empty-test ()
40 (should (streamp (stream-empty)))
41 (should (stream-empty-p (stream-empty))))
43 (ert-deftest stream-make-test ()
44 (should (streamp (stream-range)))
45 (should (not (stream-empty-p (stream-range))))) ;; Should use stream-list or something
47 (ert-deftest stream-first-test ()
48 (should (= 3 (stream-first (stream-range 3))))
49 (should (null (stream-first (stream-empty)))))
51 (ert-deftest stream-rest-test ()
52 (should (= 4 (stream-first (stream-rest (stream-range 3)))))
53 (should (= 5 (stream-first (stream-rest (stream-rest (stream-range 3)))))))
55 (ert-deftest stream-from-iterator-test ()
56 (skip-unless (require 'generator nil t))
60 (funcall (iter-lambda ()
64 (ert-deftest stream-append-test ()
65 (should (stream-empty-p (stream-append)))
66 (should (let ((list '(1 2)))
67 (equal list (seq-into-sequence (stream-append (stream list))))))
68 (should (= (seq-elt (stream-append
73 (should (let ((stream (stream (list 0))))
74 (and (= (seq-elt (stream-append stream (stream-range 1)) 10)
76 (stream-empty-p (stream-rest stream)))))
77 (should (equal (seq-into-sequence
84 (ert-deftest stream-seqp-test ()
85 (should (seqp (stream-range))))
87 (ert-deftest stream-seq-elt-test ()
88 (should (null (seq-elt (stream-empty) 0)))
89 (should (= 0 (seq-elt (stream-range) 0)))
90 (should (= 1 (seq-elt (stream-range) 1)))
91 (should (= 10 (seq-elt (stream-range) 10))))
93 (ert-deftest stream-seq-length-test ()
94 (should (zerop (seq-length (stream-empty))))
95 (should (= 10 (seq-length (stream-range 0 10)))))
97 (ert-deftest stream-seq-doseq-test ()
98 (let ((stream (stream '(a b c d)))
100 (seq-doseq (elt stream)
102 (should (equal '(d c b a) lst))))
104 (ert-deftest stream-seq-let-test ()
105 (seq-let (first _ third &rest rest) (stream-range 2 7)
108 ;; The rest of the stream shouldn't be consumed
109 (should (streamp rest))
110 (should (= 5 (stream-first rest)))
111 (should (= 6 (stream-first (stream-rest rest))))
112 (should (stream-empty-p (stream-rest (stream-rest rest))))))
114 (ert-deftest stream-seq-subseq-test ()
118 (ert-deftest stream-seq-into-test ()
119 (should (streamp (seq-into (stream-empty) 'stream)))
120 (should (streamp (seq-into '(2 4 5) 'stream)))
121 (should (= 2 (stream-first (seq-into '(2 4 5) 'stream))))
122 (should (null (seq-into (stream-empty) 'list)))
123 (should (equal '(0 1 2 3 4 5 6 7 8 9) (seq-into (stream-range 0 10) 'list))))
125 (ert-deftest stream-seq-take-test ()
126 (should (streamp (seq-take (stream-range) 2)))
127 (should (= 0 (stream-first (seq-take (stream-range) 2))))
128 (should (= 1 (stream-first (stream-rest (seq-take (stream-range) 2)))))
129 (should (null (stream-first (stream-rest (stream-rest (seq-take (stream-range) 2))))))
130 (should (stream-empty-p (stream-rest (stream-rest (seq-take (stream-range) 2))))))
132 (ert-deftest stream-seq-drop-test ()
133 (should (streamp (seq-drop (stream-range) 2)))
134 (should (= 2 (stream-first (seq-drop (stream-range) 2))))
135 (should (= 3 (stream-first (stream-rest (seq-drop (stream-range) 2)))))
136 (should (stream-empty-p (seq-drop (stream-empty) 2))))
138 (ert-deftest stream-seq-take-while-test ()
139 (let ((stream (stream '(1 3 2 5))))
140 (should (stream-empty-p (seq-take-while #'identity (stream-empty))))
141 (should (streamp (seq-take-while #'cl-oddp stream)))
142 (should (= 1 (stream-first (seq-take-while #'cl-oddp stream))))
143 (should (= 3 (stream-first (stream-rest (seq-take-while #'cl-oddp stream)))))
144 (should (stream-empty-p (stream-rest (stream-rest (seq-take-while #'cl-oddp stream)))))))
146 (ert-deftest stream-seq-drop-while-test ()
147 (let ((stream (stream '(1 3 2 5))))
148 (should (streamp (seq-drop-while #'cl-evenp stream)))
149 (should (stream-empty-p (seq-drop-while #'identity (stream-empty))))
150 (should (= 2 (stream-first (seq-drop-while #'cl-evenp stream))))
151 (should (= 5 (stream-first (stream-rest (seq-drop-while #'cl-evenp stream)))))
152 (should (stream-empty-p (stream-rest (stream-rest (seq-drop-while #'cl-evenp stream)))))))
154 (ert-deftest stream-seq-map-test ()
155 (should (stream-empty-p (seq-map #'- (stream-empty))))
156 (should (= -1 (stream-first (seq-map #'- (stream-range 1)))))
157 (should (= -2 (stream-first (stream-rest (seq-map #'- (stream-range 1)))))))
159 (ert-deftest stream-seq-do-test ()
165 (should (equal result '(4 3 2 1 0)))))
167 (ert-deftest stream-seq-filter-test ()
168 (should (stream-empty-p (seq-filter #'cl-oddp (stream-empty))))
169 (should (stream-empty-p (seq-filter #'cl-oddp (stream-range 0 4 2))))
170 (should (= 1 (stream-first (seq-filter #'cl-oddp (stream-range 0 4)))))
171 (should (= 3 (stream-first (stream-rest (seq-filter #'cl-oddp (stream-range 0 4))))))
172 (should (stream-empty-p (stream-rest (stream-rest (seq-filter #'cl-oddp (stream-range 0 4)))))))
174 (ert-deftest stream-seq-copy-test ()
175 (should (streamp (seq-copy (stream-range))))
176 (should (= 0 (stream-first (seq-copy (stream-range)))))
177 (should (= 1 (stream-first (stream-rest (seq-copy (stream-range)))))))
179 (ert-deftest stream-range-test ()
180 (should (stream-empty-p (stream-range 0 0)))
181 (should (stream-empty-p (stream-range 3 3)))
182 (should (= 0 (stream-first (stream-range 0 6 2))))
183 (should (= 2 (stream-first (stream-rest (stream-range 0 6 2)))))
184 (should (= 4 (stream-first (stream-rest (stream-rest (stream-range 0 6 2))))))
185 (should (stream-empty-p (stream-rest (stream-rest (stream-rest (stream-range 0 6 2))))))
186 (should (= -4 (stream-first (stream-rest (stream-rest (stream-range 0 nil -2)))))))
188 (ert-deftest stream-list-test ()
189 (dolist (list '(nil '(1 2 3) '(a . b)))
190 (should (equal list (stream-to-list (stream list))))))
192 (ert-deftest stream-seq-subseq-test ()
193 (should (stream-empty-p (seq-subseq (stream-range 2 10) 0 0)))
194 (should (= (stream-first (seq-subseq (stream-range 2 10) 0 3)) 2))
195 (should (= (seq-length (seq-subseq (stream-range 2 10) 0 3)) 3))
196 (should (= (seq-elt (seq-subseq (stream-range 2 10) 0 3) 2) 4))
197 (should (= (stream-first (seq-subseq (stream-range 2 10) 1 3)) 3))
198 (should (= (seq-length (seq-subseq (stream-range 2 10) 1 3)) 2))
199 (should (= (seq-elt (seq-subseq (stream-range 2 10) 1 3) 1) 4)))
201 (ert-deftest stream-seq-map-should-not-consume-stream-elements ()
203 (stream (stream-cons (setq consumed t) (stream-empty))))
204 (seq-map #'identity stream)
205 (should-not consumed)))
207 (ert-deftest stream-pop-test ()
208 (let* ((str (stream '(1 2 3)))
209 (first (stream-pop str))
210 (stream-empty (stream-empty)))
212 (should (= 2 (stream-first str)))
213 (should (null (stream-pop stream-empty)))))
215 (provide 'stream-tests)
216 ;;; stream-tests.el ends here