(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 <chou...@gmail.com> wrote:

>
> On Sun, Feb 15, 2009 at 10:06 PM, David Nolen <dnolen.li...@gmail.com>
> 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 clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to