#lang scheme (require "checks.ss" "../set.ss") (provide set-suite) (define (check/set a-set a-list #:= [== equal?]) (check/sort (set->list a-set) a-list #:= ==)) (define-syntax-rule (test/set arg ...) (test (check/set arg ...))) (define set-suite (test-suite "set.ss" (test-suite "Constructors" (test-suite "set" (test/set (set 1 2 3) (list 1 2 3)) (test/set (set 3 2 1) (list 1 2 3)) (test/set (set 3 1 2 #:mutable? #t) (list 1 2 3)) (test/set (set 3 1 2 #:weak? #t) (list 1 2 3)) (test/set (set 3 1 2 #:compare 'eqv) (list 1 2 3)) (test/set (set 3 1 2 #:compare 'eq) (list 1 2 3))) (test-suite "empty-set" (test/set (empty-set) (list)) (test/set (empty-set #:mutable? #t) (list)) (test/set (empty-set #:weak? #t) (list)) (test/set (empty-set #:compare 'eqv) (list)) (test/set (empty-set #:compare 'eq) (list))) (test-suite "list->set" (test/set (list->set (list 1 2 3)) (list 1 2 3)) (test/set (list->set (list 3 2 1)) (list 1 2 3)) (test/set (list->set (list 3 1 2) #:mutable? #t) (list 1 2 3)) (test/set (list->set (list 3 1 2) #:weak? #t) (list 1 2 3)) (test/set (list->set (list 3 1 2) #:compare 'eqv) (list 1 2 3)) (test/set (list->set (list 3 1 2) #:compare 'eq) (list 1 2 3))) (test-suite "custom-set" (test/set (custom-set #:compare string-ci=? "A" "a" "B" "b") (list "A" "B") #:= string-ci=?) (test/set (custom-set #:compare string-ci=? #:hash string-length "A" "a" "B" "b") (list "A" "B") #:= string-ci=?) (test/set (custom-set #:compare string-ci=? #:hash string-length #:mutable? #t "A" "a" "B" "b") (list "A" "B") #:= string-ci=?))) (test-suite "Accessors" (test-suite "set-contains?" (test (check-true (set-contains? (set 1 2 3) 1))) (test (check-false (set-contains? (set 1 2 3) 4)))) (test-suite "set-empty?" (test (check-true (set-empty? (set)))) (test (check-false (set-empty? (set 1 2 3))))) (test-suite "set-count" (test (check = (set-count (set)) 0)) (test (check = (set-count (set 1 2 3)) 3))) (test-suite "set=?" (test (check-false (set=? (set 1) (set 1 2 3)))) (test (check-false (set=? (set 1 2 3) (set 1)))) (test (check-true (set=? (set 1 2 3) (set 1 2 3))))) (test-suite "subset?" (test (check-true (subset? (set 1) (set 1 2 3)))) (test (check-false (subset? (set 1 2 3) (set 1)))) (test (check-true (subset? (set 1 2 3) (set 1 2 3))))) (test-suite "proper-subset?" (test (check-true (proper-subset? (set 1) (set 1 2 3)))) (test (check-false (proper-subset? (set 1 2 3) (set 1)))) (test (check-false (proper-subset? (set 1 2 3) (set 1 2 3))))) (test-suite "set->list" (test (check/sort (set->list (set 1 2 3)) (list 1 2 3)))) (test-suite "in-set" (test (check/sort (for/list ([x (in-set (set 1 2 3))]) x) (list 1 2 3))))) (test-suite "Updaters" (test-suite "set-insert" (test/set (set-insert (set 1 2 3) 4) (list 1 2 3 4)) (test/set (set-insert (set 1 2 3) 1) (list 1 2 3))) (test-suite "set-remove" (test/set (set-remove (set 1 2 3) 1) (list 2 3)) (test/set (set-remove (set 1 2 3) 4) (list 1 2 3))) (test-suite "set-insert!" (test (let* ([s (set 1 2 3 #:mutable? #t)]) (set-insert! s 4) (check/set s (list 1 2 3 4)))) (test (let* ([s (set 1 2 3 #:mutable? #t)]) (set-insert! s 1) (check/set s (list 1 2 3))))) (test-suite "set-remove!" (test (let* ([s (set 1 2 3 #:mutable? #t)]) (set-remove! s 1) (check/set s (list 2 3)))) (test (let* ([s (set 1 2 3 #:mutable? #t)]) (set-remove! s 4) (check/set s (list 1 2 3))))) (test-suite "set-union" (test/set (set-union (set 1 2) (set 1 3) (set 2 3)) (list 1 2 3)) (test/set (set-union (set) (set 1 2) (set 3 4)) (list 1 2 3 4)) (test/set (set-union (set 1 2) (set) (set 3 4)) (list 1 2 3 4)) (test/set (set-union (set 1 2) (set 3 4) (set)) (list 1 2 3 4))) (test-suite "set-intersection" (test/set (set-intersection (set 1 2 3) (set 1 2) (set 2 3)) (list 2)) (test/set (set-intersection (set 1 2) (set 1 2 3) (set 2 3)) (list 2)) (test/set (set-intersection (set 1 2) (set 2 3) (set 1 2 3)) (list 2)) (test/set (set-intersection (set 1 2) (set 2 3) (set 1 3)) (list))) (test-suite "set-difference" (test/set (set-difference (set 1 2 3) (set 1) (set 3)) (list 2)) (test/set (set-difference (set 1 2 3 4) (set 5) (set 6)) (list 1 2 3 4)) (test/set (set-difference (set 1 2 3) (set 1 2) (set 2 3)) (list))) (test-suite "set-exclusive-or" (test/set (set-exclusive-or (set 1) (set 1 2) (set 1 2 3)) (list 1 3)) (test/set (set-exclusive-or (set 1) (set 2) (set 3)) (list 1 2 3)) (test/set (set-exclusive-or (set 1 2) (set 2 3) (set 1 3)) (list)))) (test-suite "Predicates" (test-suite "set?" (test (check-false (set? '(1 2)))) (test (check-true (set? '((1 . one) (2 . two))))) (test (check-true (set? (set 1 2 3))))) (test-suite "set-can-insert?" (test (check-true (set-can-insert? (set 1 2 3)))) (test (check-false (set-can-insert? (set 1 2 3 #:mutable? #t))))) (test-suite "set-can-remove?" (test (check-true (set-can-remove? (set 1 2 3)))) (test (check-false (set-can-remove? (set 1 2 3 #:mutable? #t))))) (test-suite "set-can-insert!?" (test (check-false (set-can-insert!? (set 1 2 3)))) (test (check-true (set-can-insert!? (set 1 2 3 #:mutable? #t))))) (test-suite "set-can-remove!?" (test (check-false (set-can-remove!? (set 1 2 3)))) (test (check-true (set-can-remove!? (set 1 2 3 #:mutable? #t)))))) (test-suite "Property" (test-suite "prop:set" (test (let () (define (never-contains? set elem) #f) (define (never-remove! set elem) (void)) (define (never-remove set elem) set) (define (always-zero set) 0) (define (no-elements set) null) (define-struct always-empty [] #:transparent #:property prop:set (vector never-contains? #f #f never-remove! never-remove always-zero no-elements)) (check-true (set? (make-always-empty))) (check/set (make-always-empty) (list)) (check-false (set-contains? (make-always-empty) 1)) (check-bad (set-insert! (make-always-empty) 2)) (check-bad (set-insert (make-always-empty) 3)) (check/set (let* ([s (make-always-empty)]) (set-remove! s 4) s) (list)) (check/set (set-remove (make-always-empty) 5) (list)) (check-true (set-empty? (make-always-empty))) (check-equal? (set->list (make-always-empty)) (list))))))))