Hi Frantisek! I can see where this is useful, and the only reason I haven't implemented something like it for a test-is already is that I don't expect it would be very commonly used outside of the very specific case of testing the language itself. Where else, other than a language specification or a math library, are you going to be testing every combination of arguments?
Secondly, remember that tests are just functions, with a little extra metadata. I thought about allowing them to accept arguments, but then I didn't know how to call them in run-tests. But you can define ordinary functions and use them in your tests. It turns out to be pretty easy to define all-all are this way: (defn all-are [pred & args] (doseq [[x y] (combinations args 2)] (is (pred x y)))) (deftest equality (all-are = 0 0.0 0M 0/1) (all-are #(and (= %1 %2) (not= (class %1) (class %2))) (sorted-map :a 1) (array-map :a 1) (hash-map :a 1))) The only disadvantage to this is that you won't get some of the nice error reporting features, like individual line numbers, that you get when you use "is" by itself. But you would have the same problem if all-all are were a macro. So I guess, overall, I'm saying you shouldn't feel limited to using just the basic constructs that the library provides. They're just building blocks for your own, larger abstractions. If there's a particular abstraction that shows up repeatedly in lots of different contexts, then I'll want to add it to the library. As for the fate of "are", I've always been a little uncertain about it because it relies heavily on the templates library. And I've always been uncertain about templates because they rely heavily on code walking and code transformation. For example, in early versions of the lazy branch, "are" didn't work, and I never could figure out why. Fundamentally, I think anonymous functions are a more robust abstraction than templates, and my future work will probably rely more on functions than templates. Still, several people have said they like "are", so I wouldn't drop it lightly. Peace, love, and happy testing... -Stuart Sierra On Mar 19, 3:28 pm, Frantisek Sodomka <fsodo...@gmail.com> wrote: > Hello Stuart & all! > > As discussed in this thread: > test-is: generating and processing testing > datahttp://groups.google.com/group/clojure/browse_frm/thread/3e84efefd7c0... > > , sometimes it is necessary to test each value against each value. Example > is zeros-are-equal (as you suggested): > > (deftest zeros-are-equal > (doall (map (fn [[a b]] (is (= a b))) > (combinations [0 0.0 0M] 2)))) > > Truth is that these combinations are more common than I thought. For > example, when testing equality of maps (test-equality in data_structures.clj > in test_clojure), values of maps equal, but their classes are not. > > (= (sorted-map :a 1) (hash-map :a 1) (array-map :a 1)) => true > > (class (sorted-map :a 1)) => clojure.lang.PersistentTreeMap > (class (hash-map :a 1)) => clojure.lang.PersistentHashMap > (class (array-map :a 1)) => clojure.lang.PersistentArrayMap > > To test for this property, we can either write down all combinations (as I > did) or write deftest function for each case (equality and non-equality). > Each of these seem too verbose to me. I see 2 different solutions: > > 1) Allow deftest (new version of it?) to accept parameters: > > (deftest each-equals-each [parameter] > (doall (map (fn [[a b]] (is (= a b))) > (combinations parameter 2)))) > > This way we could call it: > (each-equals-each [0 0.0 0M]) > and > (each-equals-each [(sorted-map :a 1) (hash-map :a 1) (array-map :a 1)]) > > 2) Create new version of 'are' - 'are-combinations' or more preferably > 'are-all', which uses 'combinations' in itself: > > (are-all (= _1 _2) > 0 0.0 0M) > => > (is (= 0 0.0)) > (is (= 0 0M)) > (is (= 0.0 0M)) > > This way we can easily do: > > (are-all (= _1 _2) > (sorted-map :a 1) (hash-map :a 1) (array-map :a 1) ) > > and > > (are-all (not= _1 _2) > (class (sorted-map :a 1)) > (class (hash-map :a 1)) > (class (array-map :a 1)) ) > > or combined? ;-) > > (are-all (and (= _1 _2) (not= (class _1) (class _2))) > (sorted-map :a 1) (hash-map :a 1) (array-map :a 1) ) > > Personally, I prefer the second solution. It looks really elegant. The first > solution - tests with parameters - is useful too and we could use it under > different conditions. > > Thank you, Frantisek > > PS: What is the status of 'are' macro? Documentation still says > "Experimental. May be removed in the future.". Do you have any plans for it? > I really like it and use it heavily in test-clojure. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---