(defmethod assert-expr 'raised? [msg form]
(let [error-type (second form)
error-meta (meta (find-var (qualify-sym error-type)))
error-str (str (ns-name (:ns error-meta)) "/" (:name error-meta))
body (rrest form)]
`(with-handler
(do
~...@body
(report :fail ~msg '~form (str ~error-str " not raised.")))
(handle ~error-type {:as err#}
(if (= (:tag err#) (symbol ~error-str))
(report :pass ~msg '~form nil)
(report :fail ~msg '~form (str ~error-str " was raised."))))
(handle *error* {:as err#}
(report :fail ~msg '~form (:tag err#))))))
Here is the macro that seems to work, any improvements much appreciated ;)
This fails when no error is raised, when the wrong error type is raised, and
I believe it's captures errors which are derived but not the exact error (is
this a weird behavior?). Your previous post about error-kit got me on the
right track. I can now define test cases like so:
(deftest test-verify-slots
(is (verify-slots [[:origin [0 0]] :width :height]))
(is (raised? *malformed-slots-error* (verify-slots [[:origin] :width
:height])))
(is (raised? *malformed-slots-error* (verify-slots [[:origin 0 0] :width
:height])))
Much nicer than those ugly Java Exceptions, no? ;)
On a last note, I've found your qualify-sym fn quite handy and have been
using it elsewhere ;)
On Sun, Feb 15, 2009 at 11:52 PM, Chouser <[email protected]> wrote:
>
> On Sun, Feb 15, 2009 at 10:06 PM, David Nolen <[email protected]>
> wrote:
> > I've been attempting to combine error-kit and test-is, but getting the
> > relation between assert-expr form in test-is and the handle form in
> > error-kit is a bit tricky. Looking at the test-is thrown? example and
> > Chouser's error-kit post on the mailing list I tried something like the
> > following:
> >
> > (defmethod assert-expr 'raised? [msg form]
> > (let [error-type (second form)
> > body (rrest form)]
> > `(with-handler
> > (do
> > ~...@body
> > (report :fail ~msg '~form nil))
> > (handle {:keys [& rest#]}
> > (let [tag# (last rest#)]
> > (println "raised!" rest# ~error-type)
> > (if (= ~error-type tag#)
> > (report :pass ~msg '~form nil)
> > (report :fail ~msg '~form nil)))))))
> >
> > The assert-expr seems OK, but I can't seem to get the error-type tag from
> > handle.
> >
> > So here's the promised feedback on handle Chouser ;)
>
> Thanks! You're a brave man for trying such a thing, when error-kit
> has such thin documentation.
>
> I think there are a couple problems. One is your attempt at using &
> in a :keys destructuring expression. It amounts to something like:
>
> (let [{:keys [& etc]} {:a 1, :b 2}]
> etc)
> -> nil
>
> You may want to use {:as err-map#} instead, and then pick out the :tag
> from the err-map# later. Or perhaps simply insert the ~error-type
> there directly.
>
> Another issue is that what is stored in the err-map's :tag value is
> the fully-qualified symbol of the error, not the value of that symbol
> (which happens to be the fn used to construct it) which is what your
> ~error-type would evaluate to. I know it's confusing, but it's how it
> had to be, since I need the name and functions don't really have names.
>
> To make things worse, getting the fully-qualified name from the macro
> argument, which is likely a symbol with a nil namespace, is a bit of a
> trick. error-kit/qualify-sym does this, but it's currently private.
> It may make sense to make that public for just the kind of shenanigans
> you're trying to pull.
>
> If this has been to dense or sketchy, let me know and I'll see if I
> can help you further. This is exactly the kind of thing error-kit
> needs to be able to do.
>
> --Chouser
>
> >
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---