git.fiddlerwoaroof.com
Browse code

chore: more tests, fixes

- add DELAY
- fix definition of OF-MAX-LENGTH
- add ignorable declaration to CONJ and DISJ
- lots of new tests

Edward Langley authored on 01/10/2022 19:00:23
Showing 4 changed files
... ...
@@ -8,7 +8,8 @@
8 8
   :author "Edward Langley <el-cl@elangley.org>"
9 9
   :license "Apache v2"
10 10
   :depends-on (:cl-ppcre
11
-               :alexandria)
11
+               :alexandria
12
+               (:require :sb-cover))
12 13
   :serial t
13 14
   :in-order-to ((test-op (test-op :data-lens/test)))
14 15
   :components ((:file "package")
... ...
@@ -20,7 +21,8 @@
20 21
   :author "Edward Langley <el-cl@elangley.org>"
21 22
   :license "Apache v2"
22 23
   :depends-on (:data-lens
23
-               :fiveam)
24
+               :fiveam
25
+               :string-case)
24 26
   :serial t
25 27
   :perform (test-op (o c)
26 28
                     (unless (symbol-call :fiveam '#:run! :data-lens.lens)
... ...
@@ -102,7 +102,7 @@
102 102
 
103 103
 (defun-ct of-max-length (len)
104 104
   (lambda (it)
105
-    (>= (length it)
105
+    (<= (length it)
106 106
         len)))
107 107
 
108 108
 (defun-ct applicable-when (fun test)
... ...
@@ -114,6 +114,7 @@
114 114
 (defmacro conj (&rest fns)
115 115
   (let ((dat (gensym "dat")))
116 116
     `(lambda (,dat)
117
+       (declare (ignorable ,dat))
117 118
        (and ,@(mapcar (lambda (fn)
118 119
                         `(funcall ,fn ,dat))
119 120
                       fns)))))
... ...
@@ -226,6 +227,13 @@
226 227
                        (apply f args))
227 228
                      r)))))
228 229
 
230
+(defun delay ()
231
+  "Return a function that always returns the last thing it was called with"
232
+  (let ((result nil))
233
+    (lambda (v)
234
+      (prog1 result
235
+        (setf result v)))))
236
+
229 237
 (defun =>> (fun1 fun2)
230 238
   (lambda (i)
231 239
     (prog1 (funcall fun1 i)
... ...
@@ -20,7 +20,7 @@
20 20
            #:transform-head #:maximizing #:zipping #:applying
21 21
            #:splice-elt #:transform-elt #:denest #:op #:defalias #:<>
22 22
            #:<>1 #:== #:• #:suffixp #:functionalize #:inc #:group-by
23
-           #:keys #:conj #:disj))
23
+           #:keys #:conj #:disj #:delay))
24 24
 
25 25
 (defpackage :data-lens.transducers.internals
26 26
   (:use :cl)
... ...
@@ -6,6 +6,18 @@
6 6
 (5am:def-suite :data-lens.lens)
7 7
 (5am:in-suite :data-lens.lens)
8 8
 
9
+(5am:def-test functionalize (:suite :data-lens.lens)
10
+  (5am:is (equal 2
11
+                 (funcall (data-lens:functionalize #'1+) 1)))
12
+  (5am:is (equal 0
13
+                 (funcall (data-lens:functionalize '1-) 1)))
14
+  (5am:is (equal 3
15
+                 (funcall (data-lens:functionalize #(0 3)) 1)))
16
+  (5am:is (equal 8
17
+                 (funcall (data-lens:functionalize
18
+                           (alexandria:plist-hash-table '(1 8 2 4)))
19
+                          1))))
20
+
9 21
 (5am:def-test == (:suite :data-lens.lens)
10 22
   (5am:is (equal t
11 23
                  (funcall (data-lens:== 1)
... ...
@@ -17,18 +29,203 @@
17 29
                  (funcall (data-lens:== (list "1") :test #'equal)
18 30
                           (list "1")))))
19 31
 
20
-(5am:def-test functionalize (:suite :data-lens.lens)
32
+(5am:def-test delay (:suite :data-lens.lens)
33
+  (5am:is (equal '((nil 1)
34
+                   (1 2)
35
+                   (2 3)
36
+                   (3 4))
37
+                 (mapcar (data-lens:juxt (data-lens:delay)
38
+                                         'identity)
39
+                         '(1 2 3 4)))))
40
+
41
+(5am:def-test of-length (:suite :data-lens.lens)
42
+  (5am:is (equal t
43
+                 (funcall (data-lens:of-length 3)
44
+                          '(1 2 3))))
45
+  (5am:is (equal nil
46
+                 (funcall (data-lens:of-length 3)
47
+                          '(2 3))))
48
+  (5am:is (equal t
49
+                 (funcall (data-lens:of-length 0)
50
+                          '())))
51
+  (5am:is (equal t
52
+                 (funcall (data-lens:of-length 1)
53
+                          '(1)))))
54
+
55
+(5am:def-test of-min-length (:suite :data-lens.lens)
56
+  (5am:is (equal t
57
+                 (funcall (data-lens:of-min-length 3)
58
+                          '(1 2 3 4 5))))
59
+  (5am:is (equal nil
60
+                 (funcall (data-lens:of-min-length 3)
61
+                          '(2 3))))
62
+  (5am:is (equal t
63
+                 (funcall (data-lens:of-min-length 0)
64
+                          '())))
65
+  (5am:is (equal t
66
+                 (funcall (data-lens:of-min-length 0)
67
+                          '(1)))))
68
+
69
+(5am:def-test of-max-length (:suite :data-lens.lens)
70
+  (5am:is (equal nil
71
+                 (funcall (data-lens:of-max-length 3)
72
+                          '(1 2 3 4 5))))
73
+  (5am:is (equal t
74
+                 (funcall (data-lens:of-max-length 3)
75
+                          '(2 3))))
76
+  (5am:is (equal t
77
+                 (funcall (data-lens:of-max-length 0)
78
+                          '())))
79
+  (5am:is (equal nil
80
+                 (funcall (data-lens:of-max-length 0)
81
+                          '(1)))))
82
+
83
+(5am:def-test applicable-when (:suite :data-lens.lens)
84
+  (5am:is (equal 1
85
+                 (funcall (data-lens:applicable-when '1+ (constantly nil))
86
+                          1)))
21 87
   (5am:is (equal 2
22
-                 (funcall (data-lens:functionalize #'1+) 1)))
23
-  (5am:is (equal 0
24
-                 (funcall (data-lens:functionalize '1-) 1)))
25
-  (5am:is (equal 3
26
-                 (funcall (data-lens:functionalize #(0 3)) 1)))
27
-  (5am:is (equal 8
28
-                 (funcall (data-lens:functionalize
29
-                           (alexandria:plist-hash-table '(1 8 2 4)))
88
+                 (funcall (data-lens:applicable-when '1+ (constantly t))
30 89
                           1))))
31 90
 
91
+(5am:def-test conj (:suite :data-lens.lens)
92
+  (5am:is (equal t
93
+                 (not
94
+                  (not
95
+                   (eval `(funcall (data-lens:conj 'oddp 'identity)
96
+                                   1))))))
97
+  (5am:is (equal nil
98
+                 (not
99
+                  (not
100
+                   (eval `(funcall (data-lens:conj 'oddp 'evenp)
101
+                                   1))))))
102
+  (5am:is (equal t
103
+                 (not
104
+                  (not
105
+                   (eval `(funcall (data-lens:conj)
106
+                                   1)))))))
107
+
108
+(5am:def-test disj (:suite :data-lens.lens)
109
+  (5am:is (equal t
110
+                 (not
111
+                  (not
112
+                   (eval `(funcall (data-lens:disj 'oddp 'identity)
113
+                                   1))))))
114
+  (5am:is (equal t
115
+                 (not
116
+                  (not
117
+                   (eval `(funcall (data-lens:disj 'oddp 'evenp)
118
+                                   1))))))
119
+  (5am:is (equal nil
120
+                 (not
121
+                  (not
122
+                   (eval `(funcall (data-lens:disj)
123
+                                   1)))))))
124
+
125
+(5am:def-test sorted (:suite :data-lens.lens)
126
+  (5am:is (equal '(1 2 3 4 5)
127
+                 (funcall (data-lens:sorted '<)
128
+                          '(5 4 3 2 1)))))
129
+
130
+(5am:def-test element (:suite :data-lens.lens)
131
+  (5am:is (equal 1
132
+                 (funcall (data-lens:element 1)
133
+                          '(0 1 2 3))))
134
+  (5am:is (equal 1
135
+                 (funcall (data-lens:element 1)
136
+                          #(0 1 2 3)))))
137
+
138
+(defclass my-map ()
139
+  ((%a :initform 1 :reader a)
140
+   (%b :initform 2 :reader b)
141
+   (%c :initform 3 :reader c)
142
+   (%d :initform 4 :reader d)))
143
+(defmethod data-lens:extract-key ((map my-map) key)
144
+  (string-case:string-case (key)
145
+    ("a" (a map))
146
+    ("b" (b map))
147
+    ("c" (c map))
148
+    ("d" (d map))))
149
+
150
+(5am:def-test key (:suite :data-lens.lens)
151
+  (5am:is (equal 1
152
+                 (funcall (data-lens:key "a")
153
+                          (alexandria:alist-hash-table
154
+                           '(("b" . 2)
155
+                             ("a" . 1)
156
+                             ("c" . 3))
157
+                           :test 'equal))))
158
+
159
+  (5am:is (equal 1
160
+                 (funcall (data-lens:key "a")
161
+                          '(("b" . 2)
162
+                            ("a" . 1)
163
+                            ("c" . 3)))))
164
+  (5am:is (equal 1
165
+                 (funcall (data-lens:key "a")
166
+                          '("b" 2
167
+                            "a" 1
168
+                            "c" 3))))
169
+
170
+  (5am:is (equal 1
171
+                 (funcall (data-lens:key "a")
172
+                          (make-instance 'my-map)))))
173
+
174
+(5am:def-test keys (:suite :data-lens.lens)
175
+  (5am:is (equal 4
176
+                 (funcall (data-lens:keys "a" "b" "c" "d")
177
+                          (list (cons "a"
178
+                                      (list "b"
179
+                                            (alexandria:alist-hash-table
180
+                                             (acons "c" (make-instance 'my-map) ())
181
+                                             :test 'equal))))))))
182
+
183
+(5am:def-test regex-match (:suite :data-lens.lens)
184
+  (5am:is (serapeum:seq=
185
+           (list "acb" #("c"))
186
+           (multiple-value-list
187
+            (funcall (data-lens:regex-match "a(.)b")
188
+                     "<acb>")))))
189
+
190
+(5am:def-test include (:suite :data-lens.lens)
191
+  (5am:is (equal '(1 3 5)
192
+                 (funcall (data-lens:include 'oddp)
193
+                          '(1 2 3 4 5 6)))))
194
+
195
+(5am:def-test exclude (:suite :data-lens.lens)
196
+  (5am:is (equal '(2 4 6)
197
+                 (funcall (data-lens:exclude 'oddp)
198
+                          '(1 2 3 4 5 6)))))
199
+
200
+(5am:def-test pick (:suite :data-lens.lens)
201
+  (5am:is (equal '(1 2 3)
202
+                 (funcall (data-lens:pick 'car)
203
+                          '((1 2) (2 3) (3 4)))))
204
+  (5am:is (equal '()
205
+                 (funcall (data-lens:pick 'car)
206
+                          '()))))
207
+
208
+(5am:def-test slice (:suite :data-lens.lens)
209
+  (5am:is (equal '(1)
210
+                 (funcall (data-lens:slice 1 2)
211
+                          '(0 1 2)))))
212
+
213
+(5am:def-test update (:suite :data-lens.lens)
214
+  (5am:is-true (funcall (data-lens:suffixp "qwer")
215
+                        "asdfqwer"))
216
+  (5am:is-true (funcall (data-lens:suffixp (mapcar 'copy-seq
217
+                                                   (list "q" "w" "e" "r"))
218
+                                           :test 'equal)
219
+                        '("a" "s" "d" "f" "q" "w" "e" "r")))
220
+  (5am:is-false (funcall (data-lens:suffixp "qwer")
221
+                         "qwerasdf"))
222
+  (5am:is-false (funcall (data-lens:suffixp (mapcar 'copy-seq
223
+                                                    (list "q" "w" "e" "r"))
224
+                                            :test 'equal)
225
+                         '("q" "w" "e" "r" "a" "s" "d" "f"))))
226
+
227
+(5am:def-test suffixp (:suite :data-lens.lens))
228
+
32 229
 (5am:def-test on (:suite :data-lens.lens :depends-on (and functionalize))
33 230
   (5am:is (equal 2
34 231
                  (funcall (data-lens:on '1+ 'car)