clucumber 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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))))