koans with signals, errors and stuff
this is a bit complicated, espeially with different objects representing conditions and how hard it is to check inner parts of expressions
This commit is contained in:
parent
f4759c5685
commit
b4fe711abb
|
@ -101,7 +101,7 @@
|
||||||
(very-silly-condition #'handle-very-silly-condition)
|
(very-silly-condition #'handle-very-silly-condition)
|
||||||
(most-silly-condition #'handle-most-silly-condition))
|
(most-silly-condition #'handle-most-silly-condition))
|
||||||
(signal (make-condition 'most-silly-condition)))
|
(signal (make-condition 'most-silly-condition)))
|
||||||
(assert-equal ____ *list*)))
|
(assert-equal '(:most-silly-condition :very-silly-condition :silly-condition) *list*)))
|
||||||
|
|
||||||
(define-test multiple-handler-binds
|
(define-test multiple-handler-binds
|
||||||
;; It is possible to bind handlers in steps.
|
;; It is possible to bind handlers in steps.
|
||||||
|
@ -110,7 +110,7 @@
|
||||||
(most-silly-condition #'handle-most-silly-condition))
|
(most-silly-condition #'handle-most-silly-condition))
|
||||||
(handler-bind ((very-silly-condition #'handle-very-silly-condition))
|
(handler-bind ((very-silly-condition #'handle-very-silly-condition))
|
||||||
(signal (make-condition 'most-silly-condition))))
|
(signal (make-condition 'most-silly-condition))))
|
||||||
(assert-equal ____ *list*)))
|
(assert-equal '(:most-silly-condition :silly-condition :very-silly-condition) *list*)))
|
||||||
|
|
||||||
(define-test same-handler
|
(define-test same-handler
|
||||||
;; The same handler may be bound multiple times.
|
;; The same handler may be bound multiple times.
|
||||||
|
@ -121,7 +121,7 @@
|
||||||
(silly-condition #'handle-silly-condition)
|
(silly-condition #'handle-silly-condition)
|
||||||
(very-silly-condition #'handle-very-silly-condition))
|
(very-silly-condition #'handle-very-silly-condition))
|
||||||
(signal (make-condition 'most-silly-condition))))
|
(signal (make-condition 'most-silly-condition))))
|
||||||
(assert-equal ____ *list*)))
|
(assert-equal '(:silly-condition :silly-condition :very-silly-condition :silly-condition :very-silly-condition ) *list*)))
|
||||||
|
|
||||||
(define-test handler-types
|
(define-test handler-types
|
||||||
;; A handler is not executed if it does not match the condition type.
|
;; A handler is not executed if it does not match the condition type.
|
||||||
|
@ -130,7 +130,7 @@
|
||||||
(very-silly-condition #'handle-very-silly-condition)
|
(very-silly-condition #'handle-very-silly-condition)
|
||||||
(most-silly-condition #'handle-most-silly-condition))
|
(most-silly-condition #'handle-most-silly-condition))
|
||||||
(signal (make-condition 'very-silly-condition)))
|
(signal (make-condition 'very-silly-condition)))
|
||||||
(assert-equal ____ *list*)))
|
(assert-equal '(:very-silly-condition :silly-condition) *list*)))
|
||||||
|
|
||||||
(define-test handler-transfer-of-control
|
(define-test handler-transfer-of-control
|
||||||
;; A handler may decline to handle the condition if it returns normally,
|
;; A handler may decline to handle the condition if it returns normally,
|
||||||
|
@ -143,7 +143,7 @@
|
||||||
(return-from my-block)))
|
(return-from my-block)))
|
||||||
(silly-condition #'handle-silly-condition))
|
(silly-condition #'handle-silly-condition))
|
||||||
(signal (make-condition 'silly-condition))))
|
(signal (make-condition 'silly-condition))))
|
||||||
(assert-equal ____ *list*)))
|
(assert-equal '(:silly-condition) *list*)))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@
|
||||||
(handler-case (signal (make-condition 'my-error))
|
(handler-case (signal (make-condition 'my-error))
|
||||||
(error (condition) (handle-error condition))
|
(error (condition) (handle-error condition))
|
||||||
(my-error (condition) (handle-my-error condition)))
|
(my-error (condition) (handle-my-error condition)))
|
||||||
(assert-equal ____ *list*)))
|
(assert-equal '(:error) *list*))) ; well, I don't really understand that
|
||||||
|
|
||||||
(define-test handler-case-order
|
(define-test handler-case-order
|
||||||
;; The order of handler cases matters.
|
;; The order of handler cases matters.
|
||||||
|
@ -171,7 +171,7 @@
|
||||||
(handler-case (signal (make-condition 'my-error))
|
(handler-case (signal (make-condition 'my-error))
|
||||||
(my-error (condition) (handle-my-error condition))
|
(my-error (condition) (handle-my-error condition))
|
||||||
(error (condition) (handle-error condition)))
|
(error (condition) (handle-error condition)))
|
||||||
(assert-equal ____ *list*)))
|
(assert-equal '(:my-error) *list*)))
|
||||||
|
|
||||||
(define-test handler-case-type
|
(define-test handler-case-type
|
||||||
;; A handler cases is not executed if it does not match the condition type.
|
;; A handler cases is not executed if it does not match the condition type.
|
||||||
|
@ -179,7 +179,16 @@
|
||||||
(handler-case (signal (make-condition 'error))
|
(handler-case (signal (make-condition 'error))
|
||||||
(my-error (condition) (handle-my-error condition))
|
(my-error (condition) (handle-my-error condition))
|
||||||
(error (condition) (handle-error condition)))
|
(error (condition) (handle-error condition)))
|
||||||
(assert-equal ____ *list*)))
|
(assert-equal '(:error) *list*)))
|
||||||
|
|
||||||
|
;;; it seems that difference between #'handler-case and #'handler-bind
|
||||||
|
;; is that first is like try-catch, where single, first condition for signal is executed
|
||||||
|
;; (and expressions are not handlers, but things to evaluate)
|
||||||
|
;; and handler-bind executes all handlers applicable?
|
||||||
|
;; here handlers are functions
|
||||||
|
;; http://www.lispworks.com/documentation/HyperSpec/Body/09_ada.htm
|
||||||
|
;; here it seems that handler can either transfer control - by return-from of return
|
||||||
|
;; and that "handles" the signal, or "decline" by returning, that that means that following handlers get called
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
@ -199,27 +208,27 @@
|
||||||
(handler-case (divide numerator denominator)
|
(handler-case (divide numerator denominator)
|
||||||
(division-by-zero () :division-by-zero)
|
(division-by-zero () :division-by-zero)
|
||||||
(type-error () :type-error))))
|
(type-error () :type-error))))
|
||||||
(assert-equal ____ (try-to-divide 6 2))
|
(assert-equal 3 (try-to-divide 6 2))
|
||||||
(assert-equal ____ (try-to-divide 6 0))
|
(assert-equal :division-by-zero (try-to-divide 6 0))
|
||||||
(assert-equal ____ (try-to-divide 6 :zero))))
|
(assert-equal :type-error (try-to-divide 6 :zero))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
;;; Condition objects can contain metadata about the specific situation that
|
;;; Condition objects can contain metadata about the specific situation that
|
||||||
;;; occurred in the code.
|
;;; occurred in the code.
|
||||||
|
|
||||||
(define-test accessors-division-by-zero
|
(define-test accessors-division-by-zero
|
||||||
(let ((condition (handler-case (divide 6 0) (division-by-zero (c) c))))
|
(setq my-cond (handler-case (divide 6 0) (division-by-zero (c) c)))
|
||||||
|
(let ((my-cond (handler-case (divide 6 0) (division-by-zero (c) c))))
|
||||||
;; Disabled on CLISP and ABCL due to conformance bugs.
|
;; Disabled on CLISP and ABCL due to conformance bugs.
|
||||||
;; See https://gitlab.com/gnu-clisp/clisp/-/issues/22
|
;; See https://gitlab.com/gnu-clisp/clisp/-/issues/22
|
||||||
;; See https://github.com/armedbear/abcl/issues/177
|
;; See https://github.com/armedbear/abcl/issues/177
|
||||||
#-(or clisp abcl)
|
#-(or clisp abcl)
|
||||||
(assert-equal ____ (arithmetic-error-operands condition))
|
(assert-equal '(6 0) (arithmetic-error-operands my-cond)) ; returns '(6 0)
|
||||||
(let ((operation (arithmetic-error-operation condition)))
|
(let ((operation (arithmetic-error-operation my-cond))) ; returns #'/ holy cow
|
||||||
;; Disabled on ABCL due to a conformance bug.
|
;; Disabled on ABCL due to a conformance bug.
|
||||||
;; See https://github.com/armedbear/abcl/issues/177
|
;; See https://github.com/armedbear/abcl/issues/177
|
||||||
#-abcl
|
#-abcl
|
||||||
(assert-equal ____ (funcall operation 12 4)))))
|
(assert-equal 3 (funcall operation 12 4)))))
|
||||||
|
|
||||||
(define-test accessors-type-error
|
(define-test accessors-type-error
|
||||||
(let ((condition (handler-case (divide 6 :zero) (type-error (c) c))))
|
(let ((condition (handler-case (divide 6 :zero) (type-error (c) c))))
|
||||||
|
|
Loading…
Reference in New Issue