Skip to content

Commit

Permalink
Fix streams tests and testing sequence length.
Browse files Browse the repository at this point in the history
For now, we need to test streams before lists and sequences (the built-in kind),
because the current stable version of `stream.el` implements streams as lists.

- Fix functions `loopy--seq-length=` and `loopy--seq-length>`.  Add tests
  of the same name.

- Test that we correctly signal an error when a list or stream is too short.

- Fix test `substream-destr`. Add test `substream-destr-too-short`.
  • Loading branch information
okamsn committed Dec 12, 2024
1 parent d807bc2 commit 1dc82d9
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 15 deletions.
30 changes: 18 additions & 12 deletions loopy-destructure.el
Original file line number Diff line number Diff line change
Expand Up @@ -548,22 +548,28 @@ MAP-OR-KEY-VARS is whether there are map or key variables."

(defun loopy--seq-length= (seq n)
"Check whether the length of SEQ is equal to N."
(if (sequencep seq)
(compat-call length= seq n)
(= (seq-length seq) n)))
;; TODO: Simplify when `stream.el' is updated and streams are no longer
;; implemented as lists. See also `loopy--seq-length>'.
(cond
((streamp seq)
;; Avoid traversing long streams.
(let ((s (seq-drop seq (1- n))))
(and (not (stream-empty-p s))
(stream-empty-p (stream-rest s)))))
((listp seq)
(compat-call length= seq n))
(t
(= (seq-length seq) n))))

(defun loopy--seq-length> (seq n)
"Check whether the length of SEQ is greater than to N."
(cond
((sequencep seq)
(compat-call length> seq n))
;; Take advantage of lazy evaluation of streams.
((streamp seq)
(not (stream-empty-p (seq-drop seq n))))
((seqp seq)
(> (seq-length seq) n))
(t
(error "Not a known sequence type"))))
;; Test streams first, because version 2.3.0 of `stream.el' implements
;; streams as lists. Take advantage of lazy evaluation of streams.
((streamp seq) (not (stream-empty-p (seq-drop seq n))))
;; `length>' only seems to matter for lists, based on its definition.
((listp seq) (compat-call length> seq n))
(t (> (seq-length seq) n))))

(defun loopy--pcase-pat-positional-&seq-pattern (pos-vars opt-vars rest-var map-or-key-vars)
"Build a pattern for the positional, `&optional', and `&rest' variables.
Expand Down
20 changes: 20 additions & 0 deletions tests/misc-tests.el
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,26 @@ INPUT is the destructuring usage. OUTPUT-PATTERN is what to match."

;;; Minor Functions

(ert-deftest loopy--seq-length= ()
(should (equal t (loopy--seq-length= '(1 2 3) 3)))
(should (equal t (loopy--seq-length= [1 2 3 4] 4)))
(should (equal t (loopy--seq-length= (stream [1 2 3 4 5]) 5))))

(ert-deftest loopy--seq-length> ()
(should (equal t (loopy--seq-length> '(1 2 3) 2)))
(should (equal t (loopy--seq-length> [1 2 3 4] 3)))
(should (equal t (loopy--seq-length> (stream [1 2 3 4 5]) 4))))

(ert-deftest list-too-short ()
(should-error (loopy-let* (((a b c) '(a b)))
(list a b c))
:type '(loopy-bad-run-time-destructuring (loopy (a b c)) (a b))))

(ert-deftest stream-too-short ()
(should-error (loopy-let* (((&seq a b c) (stream '(a b))))
(list a b c))
:type '(loopy-bad-run-time-destructuring (loopy (a b c)) (a b))))

(ert-deftest loopy--member-p ()
(should (loopy--member-p '((a . 1) (b . 2))
'(2 . c)
Expand Down
17 changes: 14 additions & 3 deletions tests/tests.el
Original file line number Diff line number Diff line change
Expand Up @@ -3018,12 +3018,23 @@ Using numbers directly will use less variables and more efficient code."

(loopy-deftest substream-destr
:result '((0 1 2)
(1 2 nil)
(2 nil nil))
(1 2 3)
(2 3 4))
:body ((cycle 3)
(substream (&seq i j k) (loopy-test-escape (stream [0 1 2 3 4 5 6])))
(collect (list i j k)))
:loopy t
:iter-keyword (substream collect cycle)
:iter-bare ((substream . substreaming)
(collect . collecting)
(cycle . cycling)))

(loopy-deftest substream-destr-too-short
:error loopy-bad-run-time-destructuring
:body ((substream (&seq i j k) (loopy-test-escape (stream [0 1 2])))
(collect (list i j k)))
:loopy t
:iter-keyword (substream collect)
:iter-keyword (substream collect )
:iter-bare ((substream . substreaming)
(collect . collecting)))

Expand Down

0 comments on commit 1dc82d9

Please sign in to comment.