clucumber 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. data/LICENSE +1 -1
  2. data/README.md +4 -9
  3. data/lib/clucumber/clucumber-bootstrap.lisp +32 -0
  4. data/lib/clucumber/vendor/cl-interpol/alias.lisp +55 -0
  5. data/lib/clucumber/vendor/cl-interpol/cl-interpol.asd +56 -0
  6. data/lib/clucumber/vendor/cl-interpol/load.lisp +53 -0
  7. data/lib/clucumber/vendor/cl-interpol/packages.lisp +40 -0
  8. data/lib/clucumber/vendor/cl-interpol/read.lisp +716 -0
  9. data/lib/clucumber/vendor/cl-interpol/specials.lisp +113 -0
  10. data/lib/clucumber/vendor/cl-interpol/test/packages.lisp +34 -0
  11. data/lib/clucumber/vendor/cl-interpol/test/tests.lisp +128 -0
  12. data/lib/clucumber/vendor/cl-interpol/test.lisp +177 -0
  13. data/lib/clucumber/vendor/cl-interpol/test2.lisp +6254 -0
  14. data/lib/clucumber/vendor/cl-interpol/unicode.lisp +13912 -0
  15. data/lib/clucumber/vendor/cl-interpol/util.lisp +122 -0
  16. data/lib/clucumber/vendor/cl-ppcre/api.lisp +1262 -0
  17. data/lib/clucumber/vendor/cl-ppcre/charmap.lisp +152 -0
  18. data/lib/clucumber/vendor/cl-ppcre/charset.lisp +242 -0
  19. data/lib/clucumber/vendor/cl-ppcre/chartest.lisp +98 -0
  20. data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-test.asd +34 -0
  21. data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-unicode/packages.lisp +38 -0
  22. data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-unicode/resolver.lisp +61 -0
  23. data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-unicode.asd +58 -0
  24. data/lib/clucumber/vendor/cl-ppcre/cl-ppcre.asd +79 -0
  25. data/lib/clucumber/vendor/cl-ppcre/closures.lisp +471 -0
  26. data/lib/clucumber/vendor/cl-ppcre/convert.lisp +875 -0
  27. data/lib/clucumber/vendor/cl-ppcre/errors.lisp +84 -0
  28. data/lib/clucumber/vendor/cl-ppcre/lexer.lisp +737 -0
  29. data/lib/clucumber/vendor/cl-ppcre/lispworks-defsystem.lisp +57 -0
  30. data/lib/clucumber/vendor/cl-ppcre/load.lisp +67 -0
  31. data/lib/clucumber/vendor/cl-ppcre/optimize.lisp +578 -0
  32. data/lib/clucumber/vendor/cl-ppcre/packages.lisp +68 -0
  33. data/lib/clucumber/vendor/cl-ppcre/parser.lisp +319 -0
  34. data/lib/clucumber/vendor/cl-ppcre/ppcre-tests.lisp +269 -0
  35. data/lib/clucumber/vendor/cl-ppcre/regex-class-util.lisp +555 -0
  36. data/lib/clucumber/vendor/cl-ppcre/regex-class.lisp +259 -0
  37. data/lib/clucumber/vendor/cl-ppcre/repetition-closures.lisp +833 -0
  38. data/lib/clucumber/vendor/cl-ppcre/scanner.lisp +506 -0
  39. data/lib/clucumber/vendor/cl-ppcre/specials.lisp +172 -0
  40. data/lib/clucumber/vendor/cl-ppcre/test/packages.lisp +37 -0
  41. data/lib/clucumber/vendor/cl-ppcre/test/perl-tests.lisp +150 -0
  42. data/lib/clucumber/vendor/cl-ppcre/test/tests.lisp +159 -0
  43. data/lib/clucumber/vendor/cl-ppcre/test/unicode-tests.lisp +80 -0
  44. data/lib/clucumber/vendor/cl-ppcre/util.lisp +201 -0
  45. data/lib/clucumber/vendor/cl-unicode/alias.lisp +135 -0
  46. data/lib/clucumber/vendor/cl-unicode/api.lisp +412 -0
  47. data/lib/clucumber/vendor/cl-unicode/build/char-info.lisp +133 -0
  48. data/lib/clucumber/vendor/cl-unicode/build/dump.lisp +239 -0
  49. data/lib/clucumber/vendor/cl-unicode/build/read.lisp +280 -0
  50. data/lib/clucumber/vendor/cl-unicode/build/util.lisp +182 -0
  51. data/lib/clucumber/vendor/cl-unicode/cl-unicode.asd +90 -0
  52. data/lib/clucumber/vendor/cl-unicode/conditions.lisp +54 -0
  53. data/lib/clucumber/vendor/cl-unicode/derived.lisp +120 -0
  54. data/lib/clucumber/vendor/cl-unicode/hash-tables.lisp +20 -0
  55. data/lib/clucumber/vendor/cl-unicode/lists.lisp +10 -0
  56. data/lib/clucumber/vendor/cl-unicode/methods.lisp +15 -0
  57. data/lib/clucumber/vendor/cl-unicode/packages.lisp +76 -0
  58. data/lib/clucumber/vendor/cl-unicode/specials.lisp +135 -0
  59. data/lib/clucumber/vendor/cl-unicode/test/packages.lisp +34 -0
  60. data/lib/clucumber/vendor/cl-unicode/test/tests.lisp +150 -0
  61. data/lib/clucumber/vendor/cl-unicode/test-functions.lisp +94 -0
  62. data/lib/clucumber/vendor/cl-unicode/util.lisp +274 -0
  63. data/lib/clucumber/vendor/lift/compare/fiveam-tests.lisp +14 -0
  64. data/lib/clucumber/vendor/lift/compare/lift-tests.lisp +13 -0
  65. data/lib/clucumber/vendor/lift/compare/rt-tests.lisp +16 -0
  66. data/lib/clucumber/vendor/lift/compare/xlunit-tests.lisp +15 -0
  67. data/lib/clucumber/vendor/lift/dev/changes.lisp +61 -0
  68. data/lib/clucumber/vendor/lift/dev/config.lisp +354 -0
  69. data/lib/clucumber/vendor/lift/dev/copy-file.lisp +117 -0
  70. data/lib/clucumber/vendor/lift/dev/introspection.lisp +232 -0
  71. data/lib/clucumber/vendor/lift/dev/lift-interface.lisp +56 -0
  72. data/lib/clucumber/vendor/lift/dev/lift-notes.lisp +202 -0
  73. data/lib/clucumber/vendor/lift/dev/lift-randomized.lisp +45 -0
  74. data/lib/clucumber/vendor/lift/dev/lift.lisp +2383 -0
  75. data/lib/clucumber/vendor/lift/dev/macros.lisp +229 -0
  76. data/lib/clucumber/vendor/lift/dev/measuring.lisp +156 -0
  77. data/lib/clucumber/vendor/lift/dev/packages.lisp +161 -0
  78. data/lib/clucumber/vendor/lift/dev/port.lisp +151 -0
  79. data/lib/clucumber/vendor/lift/dev/prototypes.lisp +282 -0
  80. data/lib/clucumber/vendor/lift/dev/random-testing.lisp +124 -0
  81. data/lib/clucumber/vendor/lift/dev/report-locations.lisp +13 -0
  82. data/lib/clucumber/vendor/lift/dev/reports.lisp +916 -0
  83. data/lib/clucumber/vendor/lift/dev/utilities.lisp +242 -0
  84. data/lib/clucumber/vendor/lift/docs/package.lisp +6 -0
  85. data/lib/clucumber/vendor/lift/docs/setup.lisp +17 -0
  86. data/lib/clucumber/vendor/lift/examples/basic-examples.lisp +289 -0
  87. data/lib/clucumber/vendor/lift/examples/random-testing.lisp +32 -0
  88. data/lib/clucumber/vendor/lift/lift-documentation.asd +28 -0
  89. data/lib/clucumber/vendor/lift/lift-test.asd +35 -0
  90. data/lib/clucumber/vendor/lift/lift.asd +77 -0
  91. data/lib/clucumber/vendor/lift/test/equality-tests.lisp +40 -0
  92. data/lib/clucumber/vendor/lift/test/finding-tests.lisp +32 -0
  93. data/lib/clucumber/vendor/lift/test/lift-test.lisp +783 -0
  94. data/lib/clucumber/vendor/lift/test/order-of-operations.lisp +54 -0
  95. data/lib/clucumber/vendor/lift/test/packages.lisp +17 -0
  96. data/lib/clucumber/vendor/lift/test/test-config-files.lisp +20 -0
  97. data/lib/clucumber/vendor/lift/test/test-dynamic-variables.lisp +57 -0
  98. data/lib/clucumber/vendor/lift/test/test-maximum-problems.lisp +74 -0
  99. data/lib/clucumber/vendor/lift/test/test-prototypes.lisp +278 -0
  100. data/lib/clucumber/vendor/lift/test/test-timeout.lisp +37 -0
  101. data/lib/clucumber/vendor/lift/test/tests-in-progress.lisp +62 -0
  102. data/lib/clucumber/vendor/lift/test/testsuite-expects.lisp +60 -0
  103. data/lib/clucumber/vendor/lift/timeout/package.lisp +13 -0
  104. data/lib/clucumber/vendor/lift/timeout/with-timeout.lisp +123 -0
  105. data/lib/clucumber/vendor/lift/website/stuff/Temp.lisp +34 -0
  106. data/lib/clucumber/vendor/st-json/st-json.asd +3 -0
  107. data/lib/clucumber/vendor/st-json/st-json.lisp +310 -0
  108. data/lib/clucumber/vendor/trivial-backtrace/dev/backtrace.lisp +127 -0
  109. data/lib/clucumber/vendor/trivial-backtrace/dev/fallback.lisp +10 -0
  110. data/lib/clucumber/vendor/trivial-backtrace/dev/map-backtrace.lisp +103 -0
  111. data/lib/clucumber/vendor/trivial-backtrace/dev/mucking.lisp +75 -0
  112. data/lib/clucumber/vendor/trivial-backtrace/dev/packages.lisp +13 -0
  113. data/lib/clucumber/vendor/trivial-backtrace/dev/utilities.lisp +104 -0
  114. data/lib/clucumber/vendor/trivial-backtrace/test/packages.lisp +5 -0
  115. data/lib/clucumber/vendor/trivial-backtrace/test/test-setup.lisp +4 -0
  116. data/lib/clucumber/vendor/trivial-backtrace/test/tests.lisp +16 -0
  117. data/lib/clucumber/vendor/trivial-backtrace/trivial-backtrace-test.asd +22 -0
  118. data/lib/clucumber/vendor/trivial-backtrace/trivial-backtrace.asd +35 -0
  119. data/lib/clucumber/vendor/usocket/backend/allegro.lisp +199 -0
  120. data/lib/clucumber/vendor/usocket/backend/armedbear.lisp +491 -0
  121. data/lib/clucumber/vendor/usocket/backend/clisp.lisp +260 -0
  122. data/lib/clucumber/vendor/usocket/backend/cmucl.lisp +266 -0
  123. data/lib/clucumber/vendor/usocket/backend/lispworks.lisp +741 -0
  124. data/lib/clucumber/vendor/usocket/backend/mcl.lisp +369 -0
  125. data/lib/clucumber/vendor/usocket/backend/openmcl.lisp +206 -0
  126. data/lib/clucumber/vendor/usocket/backend/sbcl.lisp +424 -0
  127. data/lib/clucumber/vendor/usocket/backend/scl.lisp +261 -0
  128. data/lib/clucumber/vendor/usocket/condition.lisp +227 -0
  129. data/lib/clucumber/vendor/usocket/package.lisp +82 -0
  130. data/lib/clucumber/vendor/usocket/server.lisp +45 -0
  131. data/lib/clucumber/vendor/usocket/test/package.lisp +13 -0
  132. data/lib/clucumber/vendor/usocket/test/test-usocket.lisp +166 -0
  133. data/lib/clucumber/vendor/usocket/usocket-test.asd +26 -0
  134. data/lib/clucumber/vendor/usocket/usocket.asd +37 -0
  135. data/lib/clucumber/vendor/usocket/usocket.lisp +542 -0
  136. data/lib/clucumber/vendor/usocket/vendor/kqueue.lisp +1 -0
  137. data/lib/clucumber/vendor/usocket/vendor/split-sequence.lisp +245 -0
  138. data/lib/clucumber.rb +29 -7
  139. metadata +151 -5
@@ -0,0 +1,354 @@
1
+ (in-package #:lift)
2
+
3
+ #|
4
+
5
+ (:report-property :if-exists :supersede)
6
+ (:report-property :unique-name nil)
7
+ (:report-property :format :html)
8
+ (:report-property :name "index")
9
+ (:report-property :relative-to db.agraph.tests)
10
+
11
+ For text based reports like :describe, the report name is the filename
12
+ where the report is placed or a stream (e.g., *standard-output*).
13
+
14
+ The :name property specifies the name and type.
15
+
16
+ There are three ways to specify the directory:
17
+
18
+ 1. :full-name
19
+ 2. :relative-to
20
+ 3. the current directory (via *default-pathname-defaults*)
21
+
22
+ If :full-name is a pathname with a name and type, then these will be
23
+ used rather than :name. If :unique-name is true (and the destination
24
+ is not a stream), then the date and an integer tag will be added to the
25
+ name. E.g., the path `/tmp/lift-tests/report.txt` will become
26
+ `/tmp/lift-tests/report-2009-02-01-1.txt`.
27
+
28
+
29
+ For HTML, The report name specifies a _directory_. The :name property
30
+ is ignored.
31
+
32
+ There are three ways to specify the directory location.
33
+
34
+ 1. :full-name
35
+ 2. :relative-to
36
+ 3. the current directory (via *default-pathname-defaults*)
37
+
38
+ In all cases, the report will go into
39
+
40
+ |#
41
+
42
+ (defgeneric generate-report-summary-pathname ()
43
+ )
44
+
45
+ (defgeneric handle-config-preference (name args)
46
+ )
47
+
48
+
49
+ (defvar *current-configuration-stream* nil)
50
+
51
+ (defvar *current-asdf-system-name* nil
52
+ "Holds the name of the system being tested when using the `:generic`
53
+ configuration.
54
+
55
+ LIFT needs this to run the `:generic` configuration because this is
56
+ how it determines which configuration file to load. If you use
57
+ `asdf:test-op` then this value will be set automatically.
58
+ Otherwise, you will need to set it yourself.")
59
+
60
+ (eval-when (:load-toplevel :execute)
61
+ (when (find-package :asdf)
62
+ (defmethod asdf:perform :around ((operation asdf:test-op) (c asdf:system))
63
+ (let ((*current-asdf-system-name* (asdf:component-name c)))
64
+ (call-next-method)))))
65
+
66
+ (defun lift-relative-pathname (pathname &optional (errorp nil))
67
+ "Merges pathname with either the path to the currently loading system
68
+ \(if there is one\) or the *default-pathname-defaults*."
69
+ (let* ((asdf-package (find-package :asdf))
70
+ (srp-symbol (and asdf-package
71
+ (find-symbol (symbol-name 'system-relative-pathname)
72
+ asdf-package)))
73
+ (srp (and *current-asdf-system-name* srp-symbol)))
74
+ (labels ((try-it (path)
75
+ (let ((pathname (merge-pathnames pathname path)))
76
+ (if errorp (and pathname (probe-file pathname)) pathname))))
77
+ (or (and srp (try-it (funcall srp *current-asdf-system-name* "")))
78
+ (try-it *default-pathname-defaults*)
79
+ (not errorp)
80
+ (and (not asdf-package)
81
+ (error "Unable to use :generic configuration option because ASDF is not loaded."))
82
+ (and (not srp-symbol)
83
+ (error "Unable to use :generic configuration option because asdf:system-relative-pathname is not function bound (maybe try updating ASDF?)"))
84
+ (and (not *current-asdf-system-name*)
85
+ (error "Unable to use :generic configuration option
86
+ because the current system cannot be determined. You can either
87
+ use asdf:test-op or bind *current-asdf-system-name* yourself."))))))
88
+
89
+ (defun find-generic-test-configuration (&optional (errorp nil))
90
+ (flet ((try-it (path)
91
+ (and path (probe-file path))))
92
+ (or (try-it (lift-relative-pathname "lift-local.config" errorp))
93
+ (try-it (lift-relative-pathname "lift-standard.config" errorp))
94
+ (and errorp
95
+ (error "Unable to use :generic configuration file neither lift-local.config nor lift-standard.config can be found.")))))
96
+
97
+ (defun report-summary-pathname ()
98
+ (unique-filename (generate-report-summary-pathname)))
99
+
100
+ (defmethod generate-report-summary-pathname ()
101
+ (lift-relative-pathname "test-results/summary.sav"))
102
+
103
+ #+(or)
104
+ (generate-report-summary-pathname)
105
+
106
+ (defun run-tests-from-file (path)
107
+ (let ((real-path (cond ((eq path :generic)
108
+ (setf path
109
+ (find-generic-test-configuration t)))
110
+ (t
111
+ (probe-file path)))))
112
+ (unless real-path
113
+ (error "Unable to find configuration file ~s" path))
114
+ (setf *test-result*
115
+ (let* ((*package* *package*)
116
+ (*read-eval* nil)
117
+ (result (make-test-result path :multiple))
118
+ (*lift-dribble-pathname* nil)
119
+ (*lift-debug-output* *debug-io*)
120
+ (*lift-standard-output* *standard-output*)
121
+ (*test-break-on-errors?* nil)
122
+ (*test-do-children?* t)
123
+ (*lift-equality-test* 'equal)
124
+ (*test-print-length* :follow-print)
125
+ (*test-print-level* :follow-print)
126
+ (*lift-if-dribble-exists* :append)
127
+ (*test-result* result))
128
+ (%run-tests-from-file path)))))
129
+
130
+ (defun %run-tests-from-file (path)
131
+ (with-open-file (*current-configuration-stream* path
132
+ :direction :input
133
+ :if-does-not-exist :error)
134
+ (let ((form nil)
135
+ (run-tests-p t))
136
+ (loop while (not (eq (setf form (read *current-configuration-stream*
137
+ nil :eof nil)) :eof))
138
+ collect
139
+ (handler-bind
140
+ ((error (lambda (c) (format
141
+ *error-output*
142
+ "Error while running ~a from ~a: ~a"
143
+ form path c)
144
+ (pprint (get-backtrace c))
145
+ (invoke-debugger c))))
146
+ (destructuring-bind
147
+ (name &rest args)
148
+ form
149
+ (assert (typep name 'symbol) nil
150
+ "Each command must be a symbol and ~s is not." name)
151
+ (setf args (massage-arguments args))
152
+ (cond
153
+ ;; check for preferences first (i.e., keywords)
154
+ ((eq (symbol-package name)
155
+ (symbol-package :keyword))
156
+ ;; must be a preference
157
+ (handle-config-preference name args))
158
+ ((and run-tests-p (find-testsuite name :errorp nil))
159
+ (multiple-value-bind (_ restartedp)
160
+ (with-simple-restart (cancel-testing-from-configuration
161
+ "Cancel testing from file ~a" path)
162
+ (run-tests :suite name
163
+ :result *test-result*
164
+ :testsuite-initargs args))
165
+ (declare (ignore _))
166
+ ;; no more testing; continue to process commands
167
+ (when restartedp
168
+ (setf run-tests-p nil))))
169
+ (t
170
+ (warn "Don't understand '~s' while reading from ~s"
171
+ form path))))))))
172
+ (values *test-result*))
173
+
174
+ (defun massage-arguments (args)
175
+ (loop for arg in args collect
176
+ (cond ((and (symbolp arg)
177
+ (string= (symbol-name arg) (symbol-name '*standard-output*)))
178
+ *standard-output*)
179
+ (t arg))))
180
+
181
+ (defmethod handle-config-preference ((name t) args)
182
+ (warn "Unknown preference ~s (with arguments ~s)"
183
+ name args))
184
+
185
+ (defmethod handle-config-preference ((name (eql :include)) args)
186
+ (%run-tests-from-file (merge-pathnames (first args)
187
+ *current-configuration-stream*)))
188
+
189
+ (defconfig-variable :dribble *lift-dribble-pathname*)
190
+
191
+ (defconfig-variable :debug-output *lift-debug-output*)
192
+
193
+ (defconfig-variable :standard-output *lift-standard-output*)
194
+
195
+ (defconfig-variable :break-on-errors? *test-break-on-errors?*)
196
+
197
+ (defconfig-variable :do-children? *test-do-children?*)
198
+
199
+ (defconfig-variable :equality-test *lift-equality-test*)
200
+
201
+ (defconfig-variable :print-length *test-print-length*)
202
+
203
+ (defconfig-variable :print-level *test-print-level*)
204
+
205
+ (defconfig-variable :print-suite-names *test-print-testsuite-names*)
206
+
207
+ (defconfig-variable :print-test-case-names *test-print-test-case-names*)
208
+
209
+ (defconfig-variable :if-dribble-exists *lift-if-dribble-exists*)
210
+
211
+ (defmethod handle-config-preference ((name (eql :report-property))
212
+ args)
213
+ (setf (test-result-property *test-result* (first args)) (second args)))
214
+
215
+ (defconfig-variable :profiling-threshold *profiling-threshold*)
216
+
217
+ (defconfig-variable :count-calls-p *count-calls-p*)
218
+
219
+ (defconfig-variable :log-pathname *lift-report-pathname*)
220
+
221
+ (defconfig-variable :maximum-failures *test-maximum-failure-count*)
222
+ (defconfig-variable :maximum-failure-count *test-maximum-failure-count*)
223
+
224
+ (defconfig-variable :maximum-errors *test-maximum-error-count*)
225
+ (defconfig-variable :maximum-error-count *test-maximum-error-count*)
226
+
227
+ (defgeneric report-pathname (method &optional result))
228
+
229
+ (defmethod report-pathname :around ((method (eql :html))
230
+ &optional (result *test-result*))
231
+ (cond ((and (test-result-property result :full-pathname)
232
+ (streamp (test-result-property result :full-pathname)))
233
+ (call-next-method))
234
+ (t
235
+ (let ((old-name (test-result-property result :name))
236
+ (old-full-pathname (test-result-property result :full-pathname))
237
+ (old-unique-name (test-result-property result :unique-name)))
238
+ (unwind-protect
239
+ (progn
240
+ (setf (test-result-property result :name) t
241
+ (test-result-property result :unique-name) nil)
242
+ (let ((destination (pathname-sans-name+type (call-next-method))))
243
+ (when old-name
244
+ (setf destination
245
+ (merge-pathnames
246
+ (make-pathname :directory `(:relative ,old-name))
247
+ destination)))
248
+ (print destination)
249
+ (merge-pathnames
250
+ (make-pathname :name "index" :type "html")
251
+ (pathname-sans-name+type
252
+ (if old-unique-name
253
+ (unique-directory destination)
254
+ destination)))))
255
+ (setf (test-result-property result :name) old-name
256
+ (test-result-property result :full-pathname)
257
+ old-full-pathname
258
+ (test-result-property result :unique-name)
259
+ old-unique-name))))))
260
+
261
+ #+(or)
262
+ (defmethod report-pathname :around ((method t) &optional (result *test-result*))
263
+ "Make sure that directories exist"
264
+ (let ((output (call-next-method)))
265
+ (cond ((streamp output)
266
+ output)
267
+ (t
268
+ (ensure-directories-exist output)
269
+ output))))
270
+
271
+ (defmethod report-pathname ((method t) &optional (result *test-result*))
272
+ (let* ((given-report-name (test-result-property result :name))
273
+ (report-type (string-downcase
274
+ (ensure-string
275
+ (test-result-property result :format))))
276
+ (report-name (or (and given-report-name
277
+ (not (eq given-report-name t))
278
+ (merge-pathnames
279
+ given-report-name
280
+ (make-pathname :type report-type)))
281
+ (format nil "report.~a" report-type)))
282
+ (via nil)
283
+ (dest (or (and (setf via :full-pathname)
284
+ (test-result-property result :full-pathname)
285
+ (streamp
286
+ (test-result-property result :full-pathname))
287
+ (test-result-property result :full-pathname))
288
+ (and (setf via :full-pathname)
289
+ (test-result-property result :full-pathname)
290
+ (not (streamp
291
+ (test-result-property result :full-pathname)))
292
+ (cond ((eq given-report-name t)
293
+ (test-result-property result :full-pathname))
294
+ ((null given-report-name)
295
+ (merge-pathnames
296
+ (test-result-property result :full-pathname)
297
+ report-name))
298
+ (t
299
+ (merge-pathnames
300
+ (test-result-property result :full-pathname)
301
+ given-report-name))))
302
+ (and (setf via :relative-to)
303
+ (let ((relative-to
304
+ (test-result-property result :relative-to)))
305
+ (and relative-to
306
+ (asdf:find-system relative-to nil)
307
+ (asdf:system-relative-pathname
308
+ relative-to report-name))))
309
+ (and (setf via :current-directory)
310
+ (merge-pathnames
311
+ (make-pathname :defaults report-name)))))
312
+ (unique-name? (test-result-property result :unique-name)))
313
+ (values
314
+ (if (and unique-name? (not (streamp dest)))
315
+ (unique-filename dest)
316
+ dest)
317
+ via)))
318
+
319
+ (defmethod handle-config-preference ((name (eql :build-report))
320
+ args)
321
+ (declare (ignore args))
322
+ (let* ((format (or (test-result-property *test-result* :format)
323
+ :html))
324
+ (dest (report-pathname format *test-result*)))
325
+ (with-standard-io-syntax
326
+ (let ((*print-readably* nil))
327
+ (handler-bind
328
+ ((error
329
+ (lambda (c)
330
+ (format *debug-io*
331
+ "Error ~a while generating report (format ~s) to ~a"
332
+ c format dest)
333
+ (format *debug-io*
334
+ "~%~%Backtrace~%~%~s"
335
+ (get-backtrace c)))))
336
+ (cond
337
+ ((or (streamp dest)
338
+ (ensure-directories-exist dest)
339
+ (writable-directory-p dest))
340
+ (format *debug-io* "~&Sending report (format ~s) to ~a"
341
+ format dest)
342
+ (test-result-report
343
+ *test-result* dest format))
344
+ (t
345
+ (format *debug-io* "~&Unable to write report (format ~s) to ~a"
346
+ format dest))))))))
347
+
348
+
349
+ (defconfig :trace
350
+ "Start tracing each of the arguments to :trace."
351
+ (eval `(trace ,@args)))
352
+
353
+ (defconfig :untrace
354
+ (eval `(untrace ,@args)))
@@ -0,0 +1,117 @@
1
+ ;;;;
2
+ ;;; directly pullled from metatilities, sigh
3
+
4
+ (in-package #:lift)
5
+ ;(in-package #:metatilities)
6
+
7
+ (define-condition source/target-file-error (file-error)
8
+ ((pathname :reader source-pathname
9
+ :initarg :source-pathname)
10
+ (target-pathname :reader target-pathname
11
+ :initarg :target-pathname :initform nil))
12
+ (:report (lambda (c s)
13
+ (format s "Copy of ~S to ~S failed"
14
+ (source-pathname c) (target-pathname c))))
15
+ (:documentation "General condition for file errors that have a source and target."))
16
+
17
+ (define-condition source/target-target-already-exists-error (source/target-file-error)
18
+ ()
19
+ (:report (lambda (c s)
20
+ (format s "File action failed because target ~S already exists"
21
+ (target-pathname c))))
22
+ (:documentation "This error is signaled when the target pathname already exists."))
23
+
24
+ (define-condition source/target-source-does-not-exist-error
25
+ (source/target-file-error)
26
+ ()
27
+ (:report (lambda (c s)
28
+ (format s "File action failed because source ~S does not exist"
29
+ (source-pathname c))))
30
+ (:documentation "This error is signaled when the source file does not exist."))
31
+
32
+ (defun copy-file (from to &key (if-does-not-exist :error)
33
+ (if-exists :error))
34
+ "Copies the file designated by the non-wild pathname designator FROM
35
+ to the file designated by the non-wild pathname designator TO. The following
36
+ keyword parameters are supported:
37
+
38
+ * :if-exists
39
+ this can be either :supersede or :error (the default). If it is :error then
40
+ a source/target-target-already-exists-error will be signaled if the file designated
41
+ by the TO pathname already exists.
42
+
43
+ * :if-does-not-exist
44
+ this can be either :ignore or :error (the default). If it is :error then
45
+ a source/target-source-does-not-exist-error will be signaled if the FROM pathname
46
+ designator does not exist.
47
+ "
48
+ (assert (member if-exists '(:error :supersede))
49
+ nil
50
+ "The if-exists keyword parameter must be one of :error or :supersede. It is currently set to ~S"
51
+ if-exists)
52
+ (assert (member if-does-not-exist '(:error :ignore))
53
+ nil
54
+ "The if-does-not-exist keyword parameter must be one of :error or :ignore. It is currently set to ~S"
55
+ if-does-not-exist)
56
+ (ensure-directories-exist to)
57
+ (cond ((probe-file from)
58
+ #+:allegro
59
+ (excl.osi:copy-file
60
+ from to
61
+ :overwrite (if (eq if-exists :supersede) :ignore nil))
62
+ #-:allegro
63
+ (let ((element-type #-:cormanlisp '(unsigned-byte 8)
64
+ #+:cormanlisp 'unsigned-byte))
65
+ (with-open-file (in from :element-type element-type)
66
+ (with-open-file (out to :element-type element-type
67
+ :direction :output
68
+ :if-exists if-exists)
69
+ (unless out
70
+ (error (make-condition 'source/target-target-already-exists
71
+ :pathname from
72
+ :target-pathname to)))
73
+ (copy-stream in out))))
74
+ (values t))
75
+ (t
76
+ ;; no source file!
77
+ (ecase if-does-not-exist
78
+ ((:error) (error 'source/target-source-does-not-exist-error
79
+ :pathname from :target-pathname to))
80
+ ((:ignore) nil)))))
81
+
82
+ (defun move-file (from to &rest args &key (if-does-not-exist :error)
83
+ (if-exists :error))
84
+ (declare (dynamic-extent args)
85
+ (ignore if-exists if-does-not-exist))
86
+ (when (apply #'copy-file from to args)
87
+ (delete-file from)))
88
+
89
+ ;;; borrowed from asdf-install -- how did this ever work ?!
90
+ ;; for non-SBCL we just steal this from SB-EXECUTABLE
91
+ #-(or :digitool)
92
+ (defvar *stream-buffer-size* 8192)
93
+ #-(or :digitool)
94
+ (defun copy-stream (from to)
95
+ "Copy into TO from FROM until end of the input stream, in blocks of
96
+ *stream-buffer-size*. The streams should have the same element type."
97
+ (unless (subtypep (stream-element-type to) (stream-element-type from))
98
+ (error "Incompatible streams ~A and ~A." from to))
99
+ (let ((buf (make-array *stream-buffer-size*
100
+ :element-type (stream-element-type from))))
101
+ (loop
102
+ (let ((pos #-(or :clisp :cmu) (read-sequence buf from)
103
+ #+:clisp (ext:read-byte-sequence buf from :no-hang nil)
104
+ #+:cmu (sys:read-n-bytes from buf 0 *stream-buffer-size* nil)))
105
+ (when (zerop pos) (return))
106
+ (write-sequence buf to :end pos)))))
107
+
108
+ #+:digitool
109
+ (defun copy-stream (from to)
110
+ "Perform copy and map EOL mode."
111
+ (multiple-value-bind (reader reader-arg) (ccl::stream-reader from)
112
+ (multiple-value-bind (writer writer-arg) (ccl::stream-writer to)
113
+ (let ((datum nil))
114
+ (loop (unless (setf datum (funcall reader reader-arg))
115
+ (return))
116
+ (funcall writer writer-arg datum))))))
117
+
@@ -0,0 +1,232 @@
1
+ (in-package #:lift)
2
+
3
+ (defgeneric find-testsuite (suite &key errorp)
4
+ (:documentation "Search for a testsuite named `suite`.
5
+
6
+ The search is conducted across all packages so `suite` can be
7
+ a symbol in any package. I.e., find-testsuite looks for testsuite
8
+ classes whose symbol-name is string= to `suite`. If `errorp` is
9
+ true, then find-testsuite can raise two possible errors:
10
+
11
+ * If more than one matching testsuite is found,
12
+ then an error of type `testsuite-ambiguous` will be raised.
13
+ * If no matching testsuites are found, then an error of type
14
+ `testsuite-not-defined` will be raised.
15
+
16
+ The default for `errorp` is nil."))
17
+
18
+ (defgeneric find-test-case (suite name &key errorp)
19
+ (:documentation "Search for a test-case named `name` in a
20
+ testsuite named `suite`.
21
+
22
+ The search is conducted across all packages so `suite` and `name`
23
+ can be symbols in any package. I.e., find-test-case looks for a
24
+ testsuites and test-cases whose symbol-names are string= to
25
+ `suite` and `name`. If `errorp` is
26
+ true, then find-test-case can raise two possible errors:
27
+
28
+ * If more than one matching test-case is found,
29
+ then an error of type `test-case-ambiguous` will be raised.
30
+ * If no matching test-cases are found, then an error of type
31
+ `test-case-not-defined` will be raised.
32
+
33
+ The default for `errorp` is nil. If `suite` is nil, then
34
+ find-test-case will search for matching test-cases across
35
+ all suites. This is equivalent to the behavior of [find-test-cases][]."))
36
+
37
+ (defgeneric find-test-cases (name &key errorp)
38
+ )
39
+
40
+ ;;;;;
41
+ ;; some introspection
42
+
43
+ (defun liftpropos (string &key (include-cases? nil))
44
+ "Returns a list of testsuites whose name contains `string`."
45
+ (let ((result nil)
46
+ (name-as-string (ensure-string string)))
47
+ (flet ((add-if-match (suite-name &optional (to-add suite-name))
48
+ (when (search name-as-string (ensure-string suite-name)
49
+ :test #'char-equal)
50
+ (push to-add result))))
51
+ (map-testsuites
52
+ (lambda (suite level)
53
+ (declare (ignore level))
54
+ (let ((suite-name (class-name suite)))
55
+ (add-if-match suite-name)
56
+ (when include-cases?
57
+ (loop for method-name in (testsuite-tests suite-name) do
58
+ (add-if-match
59
+ method-name (cons suite-name method-name))))))
60
+ 'test-mixin))
61
+ (sort result #'string-lessp :key (lambda (it)
62
+ (typecase it
63
+ (atom it)
64
+ (cons (cdr it)))))))
65
+
66
+ (defun map-testsuites (fn start-at)
67
+ (let ((visited (make-hash-table)))
68
+ (labels ((do-it (suite level)
69
+ (unless (gethash suite visited)
70
+ (setf (gethash suite visited) t)
71
+ (funcall fn suite level)
72
+ (loop for subclass in (subclasses suite :proper? t) do
73
+ (do-it subclass (1+ level))))))
74
+ (do-it (find-class (find-testsuite start-at) nil) 0))))
75
+
76
+ (defun testsuites (&optional (start-at 'test-mixin))
77
+ "Returns a list of testsuite classes. The optional parameter provides
78
+ control over where in the test hierarchy the search begins."
79
+ (let ((result nil))
80
+ (map-testsuites (lambda (suite level)
81
+ (declare (ignore level))
82
+ (push suite result))
83
+ start-at)
84
+ (nreverse result)))
85
+
86
+ (defun print-tests (&key (include-cases? t) (start-at 'test-mixin) (stream t))
87
+ "Prints all of the defined test classes from :start-at on down."
88
+ (map-testsuites
89
+ (lambda (suite level)
90
+ (let ((indent (coerce (make-list (* level 3) :initial-element #\Space)
91
+ 'string))
92
+ (name (class-name suite)))
93
+ (format stream "~&~a~s (~:d)"
94
+ indent
95
+ name
96
+ (length (testsuite-methods name)))
97
+ (when include-cases?
98
+ (loop for method-name in (testsuite-tests name) do
99
+ (format stream "~&~a ~a" indent method-name)))))
100
+ start-at))
101
+
102
+ (defun list-tests (&key (include-cases? t) (start-at 'test-mixin) (stream t))
103
+ "Lists all of the defined test classes from :start-at on down."
104
+ (mapc (lambda (subclass)
105
+ (let ((subclass-name (class-name subclass)))
106
+ (format stream "~&~s (~:d)"
107
+ subclass-name
108
+ (length (testsuite-methods subclass-name)))
109
+ (when include-cases?
110
+ (loop for method-name in (testsuite-tests subclass-name) do
111
+ (format stream "~& ~a" method-name)))))
112
+ (testsuites start-at))
113
+ (values))
114
+
115
+ (defun testsuite-test-count (testsuite)
116
+ (or (and *testsuite-test-count*
117
+ (prog1 *testsuite-test-count* (incf *testsuite-test-count*)))
118
+ (length (testsuite-methods testsuite))))
119
+
120
+ (defmethod find-testsuite ((suite symbol) &key (errorp nil))
121
+ (or (testsuite-p suite)
122
+ (find-testsuite (symbol-name suite) :errorp errorp)))
123
+
124
+ (defmethod find-testsuite ((suite-name string) &key (errorp nil))
125
+ (let* ((temp nil)
126
+ (possibilities (remove-duplicates
127
+ (loop for p in (list-all-packages)
128
+ when (and (setf temp (find-symbol suite-name p))
129
+ (find-class temp nil)
130
+ (subtypep temp 'test-mixin)) collect
131
+ temp))))
132
+ (cond ((null possibilities)
133
+ (when errorp
134
+ (error 'testsuite-not-defined :testsuite-name suite-name)))
135
+ ((= (length possibilities) 1)
136
+ (first possibilities))
137
+ (t
138
+ (if errorp
139
+ (error 'testsuite-ambiguous
140
+ :testsuite-name suite-name
141
+ :possible-matches possibilities))
142
+ possibilities))))
143
+
144
+ (defun test-case-p (suite-class name)
145
+ (find-method #'lift-test nil `(,suite-class (eql ,name)) nil))
146
+
147
+ #+(or)
148
+ (test-case-p
149
+ (find-class (find-testsuite 'test-cluster-indexing-locally) nil)
150
+ 'db.agraph.tests::index-them)
151
+
152
+ #+(or)
153
+ (find-test-case (find-class (find-testsuite 'test-cluster-indexing-locally))
154
+ 'index-themxx)
155
+
156
+ (defmethod find-test-case ((suite symbol) name &key (errorp nil))
157
+ (find-test-case (find-class (find-testsuite suite)) name :errorp errorp))
158
+
159
+ (defmethod find-test-case ((suite null) name &key (errorp nil))
160
+ (find-test-cases name :errorp errorp))
161
+
162
+ (defmethod find-test-case ((suite test-mixin) name &key (errorp nil))
163
+ (find-test-case (class-of suite) name :errorp errorp))
164
+
165
+ (defmethod find-test-case ((suite-class standard-class) (name symbol)
166
+ &key (errorp nil))
167
+ (or (and (test-case-p suite-class name) name)
168
+ (find-test-case suite-class (symbol-name name) :errorp errorp)))
169
+
170
+ (defmethod find-test-case ((suite test-mixin) (name string)
171
+ &key (errorp nil))
172
+ (find-test-case (class-of suite) name :errorp errorp))
173
+
174
+ (defmethod find-test-case ((suite-class standard-class) (name string)
175
+ &key (errorp nil))
176
+ (let* ((temp nil)
177
+ (possibilities (remove-duplicates
178
+ (loop for p in (list-all-packages)
179
+ when (and (setf temp (find-symbol name p))
180
+ (test-case-p suite-class temp)) collect
181
+ temp))))
182
+ (cond ((null possibilities)
183
+ (when errorp
184
+ (error 'test-case-not-defined
185
+ :testsuite-name suite-class :test-case-name name)))
186
+ ((= (length possibilities) 1)
187
+ (first possibilities))
188
+ (t
189
+ (when errorp
190
+ (error 'test-case-ambiguous
191
+ :testsuite-name suite-class
192
+ :test-case-name name
193
+ :possible-matches possibilities))))))
194
+
195
+ (defmethod find-test-cases ((name symbol) &key (errorp nil))
196
+ (find-test-cases (symbol-name name) :errorp errorp))
197
+
198
+ (defmethod find-test-cases ((name string) &key (errorp nil))
199
+ (let ((result nil))
200
+ (dolist (testsuite (testsuites))
201
+ (let* ((suitename (class-name testsuite))
202
+ (testname (find-symbol name (symbol-package suitename))))
203
+ (when (and testname
204
+ (test-case-p testsuite testname))
205
+ (push (cons suitename testname) result))))
206
+ (unless result
207
+ (when errorp
208
+ (error "not test-cases found")))
209
+ result))
210
+
211
+ (defun last-test-status ()
212
+ (cond ((typep *test-result* 'test-result)
213
+ (cond ((and (null (errors *test-result*))
214
+ (null (failures *test-result*)))
215
+ :success)
216
+ ((and (errors *test-result*)
217
+ (failures *test-result*))
218
+ :errors-and-failures)
219
+ ((errors *test-result*)
220
+ :errors)
221
+ ((failures *test-result*)
222
+ :failures)))
223
+ (t
224
+ nil)))
225
+
226
+ (defun suite-tested-p (suite &key (result *test-result*))
227
+ (and result
228
+ (typep *test-result* 'test-result)
229
+ (slot-exists-p result 'suites-run)
230
+ (slot-boundp result 'suites-run)
231
+ (consp (suites-run result))
232
+ (find suite (suites-run result))))