123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- ;;;; vlist.test --- VLists. -*- mode: scheme; coding: utf-8; -*-
- ;;;;
- ;;;; Ludovic Courtès <ludo@gnu.org>
- ;;;;
- ;;;; Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
- ;;;;
- ;;;; This library is free software; you can redistribute it and/or
- ;;;; modify it under the terms of the GNU Lesser General Public
- ;;;; License as published by the Free Software Foundation; either
- ;;;; version 3 of the License, or (at your option) any later version.
- ;;;;
- ;;;; This library 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
- ;;;; Lesser General Public License for more details.
- ;;;;
- ;;;; You should have received a copy of the GNU Lesser General Public
- ;;;; License along with this library; if not, write to the Free Software
- ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- (define-module (test-vlist)
- #:use-module (test-suite lib)
- #:use-module (ice-9 vlist)
- #:use-module (srfi srfi-1)
- #:use-module (srfi srfi-26))
- ;;;
- ;;; VLists.
- ;;;
- (with-test-prefix "vlist"
- (pass-if "vlist?"
- (and (vlist? vlist-null)
- (vlist? (vlist-cons 'a vlist-null))))
- (pass-if "vlist-null?"
- (vlist-null? vlist-null))
- (pass-if "vlist-cons"
- (let* ((v1 (vlist-cons 1 vlist-null))
- (v2 (vlist-cons 2 v1))
- (v3 (vlist-cons 3 v2))
- (v4 (vlist-cons 4 v3)))
- (every vlist? (list v1 v2 v3 v4))))
- (pass-if "vlist-head"
- (let* ((v1 (vlist-cons 1 vlist-null))
- (v2 (vlist-cons 2 v1))
- (v3 (vlist-cons 3 v2))
- (v4 (vlist-cons 4 v3)))
- (equal? (map vlist-head (list v1 v2 v3 v4))
- '(1 2 3 4))))
- (pass-if "vlist-tail"
- (let* ((v1 (vlist-cons 1 vlist-null))
- (v2 (vlist-cons 2 v1))
- (v3 (vlist-cons 3 v2))
- (v4 (vlist-cons 4 v3)))
- (equal? (map vlist-head
- (map vlist-tail (list v2 v3 v4)))
- '(1 2 3))))
- (pass-if "vlist->list"
- (let* ((v1 (vlist-cons 1 vlist-null))
- (v2 (vlist-cons 2 v1))
- (v3 (vlist-cons 3 v2))
- (v4 (vlist-cons 4 v3)))
- (equal? '(4 3 2 1)
- (vlist->list v4))))
- (pass-if "list->vlist"
- (equal? (vlist->list (list->vlist '(1 2 3 4 5)))
- '(1 2 3 4 5)))
- (pass-if "vlist-drop"
- (equal? (vlist->list (vlist-drop (list->vlist (iota 77)) 7))
- (drop (iota 77) 7)))
- (pass-if "vlist-cons2"
- ;; Example from Bagwell's paper, Figure 2.
- (let* ((top (list->vlist '(8 7 6 5 4 3)))
- (part (vlist-tail (vlist-tail top)))
- (test (vlist-cons 9 part)))
- (equal? (vlist->list test)
- '(9 6 5 4 3))))
- (pass-if "vlist-cons3"
- (let ((vlst (vlist-cons 'a
- (vlist-cons 'b
- (vlist-drop (list->vlist (iota 5))
- 3)))))
- (equal? (vlist->list vlst)
- '(a b 3 4))))
- (pass-if "vlist-map"
- (equal? (vlist->list (vlist-map 1+ (list->vlist '(1 2 3 4 5))))
- '(2 3 4 5 6)))
- (pass-if "vlist-length"
- (= (vlist-length (list->vlist (iota 77)))
- 77))
- (pass-if "vlist-length complex"
- (= (vlist-length (fold vlist-cons
- (vlist-drop (list->vlist (iota 77)) 33)
- (iota (- 33 7))))
- 70))
- (pass-if "vlist-ref"
- (let* ((indices (iota 111))
- (vlst (list->vlist indices)))
- (equal? (map (lambda (i)
- (vlist-ref vlst i))
- indices)
- indices)))
- (pass-if "vlist-ref degenerate"
- ;; Degenerate case where VLST contains only 1-element blocks.
- (let* ((indices (iota 111))
- (vlst (fold (lambda (i vl)
- (let ((vl (vlist-cons 'x vl)))
- (vlist-cons i (vlist-tail vl))))
- vlist-null
- indices)))
- (equal? (map (lambda (i)
- (vlist-ref vlst i))
- (reverse indices))
- indices)))
- (pass-if "vlist-filter"
- (let* ((lst (iota 33))
- (vlst (fold-right vlist-cons vlist-null lst)))
- (equal? (vlist->list (vlist-filter even? vlst))
- (filter even? lst))))
- (pass-if "vlist-delete"
- (let* ((lst '(a b c d e))
- (vlst (fold-right vlist-cons vlist-null lst)))
- (equal? (vlist->list (vlist-delete 'c vlst))
- (delete 'c lst))))
- (pass-if "vlist-take"
- (let* ((lst (iota 77))
- (vlst (fold-right vlist-cons vlist-null lst)))
- (equal? (vlist->list (vlist-take vlst 44))
- (take lst 44))))
- (pass-if "vlist-unfold"
- (let ((results (map (lambda (unfold)
- (unfold (lambda (i) (> i 100))
- (lambda (i) i)
- (lambda (i) (+ i 1))
- 0))
- (list unfold vlist-unfold))))
- (equal? (car results)
- (vlist->list (cadr results)))))
- (pass-if "vlist-append"
- (let* ((lists '((a) (b c) (d e f) (g)))
- (vlst (apply vlist-append (map list->vlist lists)))
- (lst (apply append lists)))
- (equal? lst (vlist->list vlst)))))
- ;;;
- ;;; VHash.
- ;;;
- (with-test-prefix "vhash"
- (pass-if "vhash?"
- (vhash? (vhash-cons "hello" "world" vlist-null)))
- (pass-if "vhash-assoc vlist-null"
- (not (vhash-assq 'a vlist-null)))
- (pass-if "vhash-assoc simple"
- (let ((vh (vhash-cons "hello" "world" vlist-null)))
- (equal? (cons "hello" "world")
- (vhash-assoc "hello" vh))))
- (pass-if "vhash-assoc regular"
- (let* ((keys '(a b c d e f g h i))
- (values '(1 2 3 4 5 6 7 8 9))
- (vh (fold vhash-cons vlist-null keys values)))
- (fold (lambda (k v result)
- (and result
- (equal? (cons k v)
- (vhash-assoc k vh eq?))))
- #t
- keys
- values)))
- (pass-if "vhash-assoc tail"
- (let* ((keys '(a b c d e f g h i))
- (values '(1 2 3 4 5 6 7 8 9))
- (vh1 (fold vhash-consq vlist-null keys values))
- (vh2 (vhash-consq 'x 'x (vlist-tail vh1))))
- (and (fold (lambda (k v result)
- (and result
- (equal? (cons k v)
- (vhash-assq k vh2))))
- #t
- (cons 'x (delq 'i keys))
- (cons 'x (delv 9 values)))
- (not (vhash-assq 'i vh2)))))
- (pass-if "vhash-assoc degenerate"
- (let* ((keys '(a b c d e f g h i))
- (values '(1 2 3 4 5 6 7 8 9))
- (vh (fold (lambda (k v vh)
- ;; Degenerate case where VH2 contains only
- ;; 1-element blocks.
- (let* ((vh1 (vhash-cons 'x 'x vh))
- (vh2 (vlist-tail vh1)))
- (vhash-cons k v vh2)))
- vlist-null keys values)))
- (and (fold (lambda (k v result)
- (and result
- (equal? (cons k v)
- (vhash-assoc k vh))))
- #t
- keys
- values)
- (not (vhash-assoc 'x vh)))))
- (pass-if "vhash as vlist"
- (let* ((keys '(a b c d e f g h i))
- (values '(1 2 3 4 5 6 7 8 9))
- (vh (fold vhash-cons vlist-null keys values))
- (alist (fold alist-cons '() keys values)))
- (and (equal? (vlist->list vh) alist)
- (= (length alist) (vlist-length vh))
- (fold (lambda (i result)
- (and result
- (equal? (list-ref alist i)
- (vlist-ref vh i))))
- #t
- (iota (vlist-length vh))))))
- (pass-if "vhash entry shadowed"
- (let* ((a (vhash-consq 'a 1 vlist-null))
- (b (vhash-consq 'a 2 a)))
- (and (= 1 (cdr (vhash-assq 'a a)))
- (= 2 (cdr (vhash-assq 'a b)))
- (= 1 (cdr (vhash-assq 'a (vlist-tail b)))))))
- (pass-if "vlist-filter"
- (let* ((keys '(a b c d e f g h i))
- (values '(1 2 3 4 5 6 7 8 9))
- (vh (fold vhash-cons vlist-null keys values))
- (alist (fold alist-cons '() keys values))
- (pred (lambda (k+v)
- (case (car k+v)
- ((c f) #f)
- (else #t)))))
- (let ((vh (vlist-filter pred vh))
- (alist (filter pred alist)))
- (and (equal? (vlist->list vh) alist)
- (= (length alist) (vlist-length vh))
- (fold (lambda (i result)
- (and result
- (equal? (list-ref alist i)
- (vlist-ref vh i))))
- #t
- (iota (vlist-length vh)))))))
- (pass-if "vhash-delete"
- (let* ((keys '(a b c d e f g d h i))
- (values '(1 2 3 4 5 6 7 0 8 9))
- (vh (fold vhash-cons vlist-null keys values))
- (alist (fold alist-cons '() keys values)))
- (let ((vh (vhash-delete 'd vh))
- (alist (alist-delete 'd alist)))
- (and (= (length alist) (vlist-length vh))
- (fold (lambda (k result)
- (and result
- (equal? (assq k alist)
- (vhash-assoc k vh eq?))))
- #t
- keys)))))
- (pass-if "vhash-delete honors HASH"
- ;; In 2.0.0, `vhash-delete' would construct a new vhash without
- ;; using the supplied hash procedure, which could lead to
- ;; inconsistencies.
- (let* ((s "hello")
- (vh (fold vhash-consv
- (vhash-consv s "world" vlist-null)
- (iota 300)
- (iota 300))))
- (and (vhash-assv s vh)
- (pair? (vhash-assv s (vhash-delete 123 vh eqv? hashv))))))
- (pass-if "vhash-fold"
- (let* ((keys '(a b c d e f g d h i))
- (values '(1 2 3 4 5 6 7 0 8 9))
- (vh (fold vhash-cons vlist-null keys values))
- (alist (fold alist-cons '() keys values)))
- (equal? alist (reverse (vhash-fold alist-cons '() vh)))))
- (pass-if "vhash-fold-right"
- (let* ((keys '(a b c d e f g d h i))
- (values '(1 2 3 4 5 6 7 0 8 9))
- (vh (fold vhash-cons vlist-null keys values))
- (alist (fold alist-cons '() keys values)))
- (equal? alist (vhash-fold-right alist-cons '() vh))))
- (pass-if "alist->vhash"
- (let* ((keys '(a b c d e f g d h i))
- (values '(1 2 3 4 5 6 7 0 8 9))
- (alist (fold alist-cons '() keys values))
- (vh (alist->vhash alist))
- (alist2 (vlist-fold cons '() vh)))
- (and (equal? alist (reverse alist2))
- (fold (lambda (k result)
- (and result
- (equal? (assq k alist)
- (vhash-assoc k vh eq?))))
- #t
- keys))))
- (pass-if "vhash-fold*"
- (let* ((keys (make-list 10 'a))
- (values (iota 10))
- (vh (fold vhash-cons vlist-null keys values)))
- (equal? (vhash-fold* cons '() 'a vh)
- values)))
- (pass-if "vhash-fold* tail"
- (let* ((keys (make-list 100 'a))
- (values (iota 100))
- (vh (fold vhash-cons vlist-null keys values)))
- (equal? (vhash-fold* cons '() 'a (vlist-drop vh 42))
- (take values (- 100 42)))))
- (pass-if "vhash-fold* interleaved"
- (let* ((keys '(a b a b a b a b a b c d e a b))
- (values '(1 0 2 0 3 0 4 0 5 0 0 0 0 6 0))
- (vh (fold vhash-cons vlist-null keys values)))
- (equal? (vhash-fold* cons '() 'a vh)
- (filter (cut > <> 0) values))))
- (pass-if "vhash-foldq* degenerate"
- (let* ((keys '(a b a b a a a b a b a a a z))
- (values '(1 0 2 0 3 4 5 0 6 0 7 8 9 0))
- (vh (fold (lambda (k v vh)
- ;; Degenerate case where VH2 contains only
- ;; 1-element blocks.
- (let* ((vh1 (vhash-consq 'x 'x vh))
- (vh2 (vlist-tail vh1)))
- (vhash-consq k v vh2)))
- vlist-null keys values)))
- (equal? (vhash-foldq* cons '() 'a vh)
- (filter (cut > <> 0) values)))))
|