On Fri, May 27, 2011 at 1:46 PM, nil <ache...@gmail.com> wrote:
> I was looking at 
> http://saucelabs.com/blog/index.php/2009/12/running-your-selenium-tests-in-parallel-clojure/
> and in the comments, :Scott suggested that a macro could reduce some
> of the boilerplate that you see here:
>
> (def test-google
>  {
>   :name "google"
>   :test (fn [client]
>           (doto client
>             (.open "http://www.google.com";)
>             (.type "q" "Sauce Labs")
>             (.click "btnG")
>             (.waitForPageToLoad "5000"))
>           (.isTextPresent client "Selenium"))})
>
> (def test-yahoo
>  {
>   :name "yahoo"
>   :test (fn [client]
>           (doto client
>             (.open "http://yahoo.com";)
>             (.type "p" "Sauce Labs")
>             (.click "search-submit")
>             (.waitForPageToLoad "5000"))
>           (.isTextPresent client "Selenium"))})
>
> You can see the boilerplate of defining the map, typing the names of
> the two keys, calling the thing "test-<name>" ... So I tried writing a
> macro for this. But when I use my first attempt, it says Can't use
> qualified name as parameter. Here's my first attempt:
>
> (defmacro deftest [name & body]
>  (let [test-n (symbol (str "test-" name))
>        n (str name)]
>    `(def ~test-n
>          {:name ~n
>           :test (fn [client]
>                   ~@body)})))
>
> The macro expansion of the following looks good, but actually running
> it yields the complaint mentioned above:
>
>  (deftest google
>    (doto client
>      (.open "http://www.google.com";)
>      (.type "q" "Sauce Labs")
>      (.click "btnG")
>      (.waitForPageToLoad "5000"))
>    (.isTextPresent client "Selenium"))
>
> My second attempt works ......
>
> (defmacro deftest [name client & body]
>  (let [test-n (symbol (str "test-" name))
>        n (str name)]
>    `(def ~test-n
>          {:name ~n
>           :test (fn [~client]
>                   ~@body)})))
>
> ... but now the user has to mention the client twice:
>
>  (deftest google client
>    (doto client
>      (.open "http://www.google.com";)
>      (.type "q" "Sauce Labs")
>      (.click "btnG")
>      (.waitForPageToLoad "5000"))
>    (.isTextPresent client "Selenium"))
>
> How do I get around this?

You probably shouldn't; it's considered good form in Clojure to
explicitly specify all bound names rather than to have macros
implicitly bind particular names like 'client (a practice common in
Common Lisp and called anaphora; one problem with anaphora is that it
doesn't nest -- Clojure's %, %2, etc. in #(...) closures are a case in
point).

-- 
Protege: What is this seething mass of parentheses?!
Master: Your father's Lisp REPL. This is the language of a true
hacker. Not as clumsy or random as C++; a language for a more
civilized age.

-- 
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
Note that posts from new members are moderated - please be patient with your 
first post.
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