aboutsummaryrefslogtreecommitdiff
path: root/examples/examples.lisp
blob: 99ad26e7fe24ee889987f5dbb18d26d10334be26 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
(defpackage :testiere.examples
  (:use #:cl #:testiere))

(defpackage :dummy
  (:use #:cl))

(in-package :testiere.examples)

;;; Turn Testiere On.
(testiere:on)

;;; BASIC TESTS

(defun add3 (x y z)
  "Adds three numbers"
  #+testiere
  (:tests
   (= 6 (add3 1 2 3))
   (:is (evenp (add3 2 2 2)))
   (:fails (add3))
   (:fails (add3 1 2 "oh no")))
  (+ x y z))

;;; Using external tests

(defun dummy::test-add10 (n)
  "Tests add10 in the same way N times. Obviously useless. We define
this in a separate package to give you an idea that you can embed
tests that aren't part of the package you're testing."
  (loop :repeat n :do 
    (assert (= 13 (add10 3)))))

(defun add10 (x)
  "Adds 10 to X"
  #+testiere
  (:tests
   (:funcall 'dummy::test-add10 1))
  (+ x 10))

;;; Adding some context to tests with :LET

(defvar *count*)

(defun increment-count (&optional (amount 1))
  "Increments *COUNT* by AMOUNT"
  #+testiere
  (:tests
   (:let ((*count* 5))
     (:do (increment-count))
     (= *count* 6)
     (:do (increment-count 4))
     (= *count* 10))
   (:let ((*count* -10))
     (= (increment-count) -9)))
  (incf *count* amount))

;;; Stubbing functions with :WITH-DEFUNS

(defun dummy::make-drakma-request (url)
  "Assume this actually makes an HTTP request using drakma"
  )

(defun test-count-words-in-response ()
  (assert (= 3 (count-words-in-response "blah"))))

(defun count-words-in-response (url)
  "Fetches a url and counts the words in the response."
  #+testiere
  (:tests
   (:with-defuns
       ((dummy::make-drakma-request (url)
                                    (declare (values (simple-array character)))
                                    "Hello     there    dudes"))
     (= 3 (count-words-in-response "dummy-url"))
     (:funcall 'test-count-words-in-response)))
  (loop
    :with resp string := (dummy::make-drakma-request url)
    :with in-word? := nil
    :for char :across resp
    :when (and in-word? (not (alphanumericp char)))
      :count 1 :into wc
      :and :do (setf in-word? nil)
    :when (alphanumericp char)
      :do (setf in-word? t)
    :finally (return
               (if (alphanumericp char) (1+ wc) wc))))

;;; Testing Classes

(defclass point ()
  ((x
    :accessor px
    :initform 0
    :initarg :x)
   (y
    :accessor py
    :initform 0
    :initarg :y))
  #+testiere
  (:tests
   (:let ((pt (make-instance 'point :x 10 :y 20)))
     (= 20 (py pt))
     (= 10 (px pt))
     (:is (< (px pt) (py pt))))))

;;; Testing Structs

(defstruct pt
  x y
  #+testiere
  (:tests
   (:let ((pt (make-pt :x 10 :y 20)))
     (= 20 (pt-y pt))
     (:is (< (pt-x pt) (pt-y pt))))))

;;; Testing Types

(deftype optional-int ()
  #+testiere
  (:tests
   (:is (typep nil 'optional-int))
   (:is (typep 10 'optional-int))
   (:is (not (typep "foo" 'optional-int))))
  '(or integer null))