(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 -~----------~----~----~----~------~----~------~--~---