ANN: ClojureScript 0.0-2496, cljs.test - a clojure.test port

557 views
Skip to first unread message

David Nolen

unread,
Dec 17, 2014, 4:54:09 PM12/17/14
to clojure, clojur...@googlegroups.com
ClojureScript, the Clojure compiler that emits JavaScript source code.

README and source code: https://github.com/clojure/clojurescript

New release version: 0.0-2496

Leiningen dependency information:

[org.clojure/clojurescript "0.0-2496"]

The big change in this release is a port of the clojure.test namespace
- cljs.test.
It is largely compatible with clojure.test and implements enough
functionality such
that we could port all of the existing tests to it. It's also featureful enough
to support a ClojureScript port of test.check that is underway.
cljs.test is compatible
with all of the optimization settings provided by the compiler including :none.

Still cljs.test may not satisfy all the patterns that people have come to expect
from clojure.test so feedback (and enhancement/fix patches) is very welcome.

On the way we implemented changes to the compiler in order to make
custom testing
frameworks simpler to implement - this includes compiler support for
:test metadata as well
as introducing static vars.

ClojureScript does not have vars, however there are var patterns that
are largely
static in nature and useful for metaprogramming and REPL interactions. Towards
this end we've implemented the `var` special form and introduced very restricted
functionality - metadata is the primary use case.

(defn foo [])
(meta #'foo) ;; will return the expected metadata

cljs.test is implemented on top of this functionality as well as a new namespace
cljs.analyzer.api which I think macro writers will find quite useful.

Also there's a doc macro now in the cljs.repl namespace that works as expected.
Patches welcome to bring all the useful bits of clojure.repl into cljs.repl.

## 0.0-2496

### Enhancements
* cljs.test added, mirrors clojure.test
* New cljs.analyzer.api namespace for easier access to analysis info from macros
* New cljs.analyzer.api namespace for easier access to analysis info from macros
* Support :test metadata on vars
* Support static vars
* cljs.source-map for client side source mapping
* expose ClojureScript :warnings build option
* CLJS-909: Add stable api for consumers of compiler data.

### Changes
* convert all ClojureScript tests to cljs.test
* add volatile! from Clojure 1.7
* stateful transducers use volatile!
* added `js-debugger` macro, compiles to "debugger;"
* CLJS-892: Improve performance of compare-symbols/compare-keywords
* CLJS-696: remove arguments usage from defrecord constructor
* unroll `partial`, copy & pasted from Clojure core.clj
* optimize clojure.string/join

### Fixes
* fix `cljs.nodejs/enable-util-print!`, incorrectly monkey patched
`cjls.core/string-print` instead of setting `cljs.core/*print-fn*`
* cljs.reader bug, '/ incorrectly read
* avoid emitting the same goog.require

Mimmo Cosenza

unread,
Dec 17, 2014, 5:10:36 PM12/17/14
to clojur...@googlegroups.com, clo...@googlegroups.com
thanks so much David!
mimmo
> --
> Note that posts from new members are moderated - please be patient with your first post.
> ---
> You received this message because you are subscribed to the Google Groups "ClojureScript" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to clojurescrip...@googlegroups.com.
> To post to this group, send email to clojur...@googlegroups.com.
> Visit this group at http://groups.google.com/group/clojurescript.

Dom Kiva-Meyer

unread,
Dec 17, 2014, 5:16:12 PM12/17/14
to clojur...@googlegroups.com, clojure
Thank you! This is awesome news.

Shaun LeBron

unread,
Dec 17, 2014, 5:39:22 PM12/17/14
to clojur...@googlegroups.com, clo...@googlegroups.com
really exciting stuff, thanks a lot

Nikita Beloglazov

unread,
Dec 17, 2014, 6:37:05 PM12/17/14
to clojur...@googlegroups.com, clo...@googlegroups.com
Does cljs.test support asynchronous tests? What are benefits of cljs.test over clojurescript.test (https://github.com/cemerick/clojurescript.test)? Clojurescript.test also a port of clojure.test but has additional API for writing asynchronous tests.

James MacAulay

unread,
Dec 17, 2014, 6:41:31 PM12/17/14
to clojur...@googlegroups.com, clo...@googlegroups.com
Looks great, thanks so much!

I was happy to see the "TODO: support async" comment in test.clj, as I am currently using Chas Emerick's clojurescript.test for very async-heavy stuff. I ended up writing a macro which I think improves the ergonomics of portable async testing quite a bit:

https://github.com/jamesmacaulay/zelkova/blob/32fdcecd74e5fa51a6e710625aa4e59abb6aa25e/src/cljx/jamesmacaulay/async_tools/test.cljx#L7-L16

...which is used like this:

https://github.com/jamesmacaulay/zelkova/blob/32fdcecd74e5fa51a6e710625aa4e59abb6aa25e/test/cljx/jamesmacaulay/zelkova/signal_test.cljx#L66-L82

I really like writing async tests like this; very little fuss. Maybe once cljs.test has async support, a testing macro like this could go into core.async?

David Nolen

unread,
Dec 19, 2014, 5:50:20 PM12/19/14
to clojure, clojur...@googlegroups.com
I just cut 0.0-2498, the only change is support for
`cljs.test/use-fixtures` analogous to `clojure.test/use-fixtures`.

David

Yehonathan Sharvit

unread,
Dec 21, 2014, 4:56:26 PM12/21/14
to clojur...@googlegroups.com, clo...@googlegroups.com
Now that var is implemented. Could we expect the support of private functions in cljs?

Yehonathan Sharvit

unread,
Dec 23, 2014, 4:59:37 PM12/23/14
to clojur...@googlegroups.com, clo...@googlegroups.com
What is the gap between clojure.test and cljs.test?

For exmaple: is the `are` macro implemented in cljs.test?

On Wednesday, 17 December 2014 23:54:09 UTC+2, David Nolen wrote:

Russell Mull

unread,
Dec 24, 2014, 12:38:55 PM12/24/14
to clo...@googlegroups.com, clojur...@googlegroups.com
Things that aren't in cljs.test:
  • with-test
  • run-tests can take a custom environment parameter. Things that required rebinding a var in clj.test are configured with an entry in the environment. 
    • :reporter, instead of rebinding the report function
    • :testing-contexts instead of *testing-contexts*
    • :testing-vars instead of *testing-vars*
And that's it. It looks like a nearly complete port. 

- Russell

Yehonathan Sharvit

unread,
Dec 24, 2014, 1:13:33 PM12/24/14
to clojur...@googlegroups.com, clo...@googlegroups.com, clojur...@googlegroups.com
What about the 'are' macro?



--
Note that posts from new members are moderated - please be patient with your first post.
---
You received this message because you are subscribed to a topic in the Google Groups "ClojureScript" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojurescript/gnCl0CySSk8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojurescrip...@googlegroups.com.

Russell Mull

unread,
Dec 24, 2014, 1:17:07 PM12/24/14
to clo...@googlegroups.com, clojur...@googlegroups.com
Yes, it's there. The things I listed are the only differences I could find. The separation of macros makes it a little confusing, but it's pretty easy to find in the source:


Russell



--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/gnCl0CySSk8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

David Nolen

unread,
Dec 24, 2014, 1:18:39 PM12/24/14
to clojur...@googlegroups.com
The `are` macro isn't in a current release, however it's in master and
will appear in the next one. Otherwise Russell's assessment is
correct.

David
> You received this message because you are subscribed to the Google Groups
> "ClojureScript" group.
> To unsubscribe from this group and stop receiving emails from it, send an

Yehonathan Sharvit

unread,
Dec 24, 2014, 1:32:17 PM12/24/14
to clojur...@googlegroups.com
Great news David!

What is the usual delay (in days) between commit to the master and release?

David Nolen

unread,
Dec 24, 2014, 1:40:03 PM12/24/14
to clojur...@googlegroups.com
Time between releases are pretty variable though they tend to be
pretty frequent around new features like cljs.test as issues need to
be ironed out.

I'll probably cut another release on Friday.

David

Yehonathan Sharvit

unread,
Dec 30, 2014, 4:27:37 AM12/30/14
to clojur...@googlegroups.com
I have played with the tutorial provided here: http://keeds.github.io/clojurescript/2014/12/19/cljs-test.html

It seems that new tests inside an existing namespace are not run when using lein cljsbuild auto test.

Is it a bug in cljs.test?

David Nolen

unread,
Dec 30, 2014, 8:49:58 AM12/30/14
to clojur...@googlegroups.com
This is a tooling issue more than anything, you need to recompile the
namespace with the `run-tests` expression.

However, there is utility to a :recompile-dependents flag, and we
already have a JIRA ticket for this. When it is implemented it will
trigger all dependent namespaces to recompile.

David

Yehonathan Sharvit

unread,
Jan 1, 2015, 12:16:05 AM1/1/15
to clojur...@googlegroups.com
Got it. Thanks.

I voted for the jira issue.

Herwig Hochleitner

unread,
Jan 5, 2015, 2:20:27 PM1/5/15
to clojurescript
It's great to see unit test support in clojurescript. Are there plans to support asynchronous tests or should I keep using cemerick's cljs.test for this?

David Nolen

unread,
Jan 5, 2015, 2:30:35 PM1/5/15
to clojur...@googlegroups.com
Definitely plans to support async and happy to take a patch.

Basically I would like sugar that looks like this:

(deftest foo
(async done
...))

This desugars into:

(deftest foo
(reify
IAsyncTest
(-invoke [_ done]
...))

The test runners should check for satisfies? IAsyncTest do nothing if
that's the return value of the test. Invoking done will gather
reporting information and invoke the next test. There should be a new
timeout parameter which fails a long running async test and continues.

David

James MacAulay

unread,
Jan 5, 2015, 7:13:21 PM1/5/15
to clojur...@googlegroups.com
On Monday, 5 January 2015 14:30:35 UTC-5, David Nolen wrote:
> The test runners should check for satisfies? IAsyncTest do nothing if
> that's the return value of the test. Invoking done will gather
> reporting information and invoke the next test.

Ooo nice idea, then we could just extend core.async's ManyToManyChannel with an implementation of IAsyncTest and that would let us use go blocks like in my aforementioned macro:

(deftest foo
(go
(is (= 1 (<! (async/to-chan [1]))))))

David Nolen

unread,
Jan 5, 2015, 8:00:17 PM1/5/15
to clojur...@googlegroups.com
That can't actually work since the go block doesn't receive the done
fn to proceed to the next test.

David

Herwig Hochleitner

unread,
Jan 5, 2015, 8:26:59 PM1/5/15
to clojurescript
2015-01-05 20:30 GMT+01:00 David Nolen <dnolen...@gmail.com>:
Definitely plans to support async and happy to take a patch.

Basically I would like sugar that looks like this:

(deftest foo
  (async done
     ...))

This desugars into:

(deftest foo
   (reify
     IAsyncTest
     (-invoke [_ done]
        ...))

The test runners should check for satisfies? IAsyncTest do nothing if
that's the return value of the test. Invoking done will gather
reporting information and invoke the next test. There should be a new
timeout parameter which fails a long running async test and continues.

Good idea! I like this somewhat better than ^:async metadata on tests, but it creates a source of (almost) silent user errors:

(deftest foo
  (async done ..)
  (async done ..))
 
Should this be the user's responsibility?
Should async register the IAsyncTest instance, so that cljs.test can complain if they aren't run?

By the same logic, IAsyncTest instances aren't easily composable. Should there be explicit primitives for doing so (one serial, one parallel)?
OTOH, if deftest with only one async child is the only "valid" idiom, should it be encouraged by a (defasynctest foo done ...) form?

kind regards

David Nolen

unread,
Jan 5, 2015, 8:38:08 PM1/5/15
to clojur...@googlegroups.com
On Mon, Jan 5, 2015 at 8:26 PM, Herwig Hochleitner <hhochl...@gmail.com> wrote:
> (deftest foo
>   (async done ..)
>   (async done ..))
>  
> Should this be the user's responsibility?

Sure preventing this would be nice. Each test only needs a single async block.

> By the same logic, IAsyncTest instances aren't easily composable. Should
> there be explicit primitives for doing so (one serial, one parallel)?
> OTOH, if deftest with only one async child is the only "valid" idiom, should
> it be encouraged by a (defasynctest foo done ...) form?

I don't really see the composition problem, tests run one after the other - the runner can handle both kinds of tests.

I don't see what the purpose of serial or parallel is nor defasynctest.

(deftest foo
  (async done
    (go
      (is (= x (<! c0))
      (is (= y (<! c1))
      (done))))

Or whatever.

James MacAulay

unread,
Jan 5, 2015, 9:12:47 PM1/5/15
to clojur...@googlegroups.com
On Monday, 5 January 2015 20:00:17 UTC-5, David Nolen wrote:
> That can't actually work since the go block doesn't receive the done
> fn to proceed to the next test.

I was thinking of something like:

(extend-type ManyToManyChannel
IAsyncTest
(-invoke [ch done]
(take! ch (fn [_] (done)))))

Wouldn't that work?

David Nolen

unread,
Jan 5, 2015, 9:34:54 PM1/5/15
to clojur...@googlegroups.com
I suppose so, just using an async block just seems cleaner and simpler to me and you're not modifying a type you don't control - not a big deal in tests but you never know.

David

puzzler

unread,
May 8, 2015, 2:49:09 AM5/8/15
to clo...@googlegroups.com, clojur...@googlegroups.com
I can't find any documentation or examples for using the new cljs.test namespace.  Can someone point me in the right direction?  Thanks.

David Nolen

unread,
May 8, 2015, 7:15:01 AM5/8/15
to clojur...@googlegroups.com
Mark,

There isn't much documentation yet as it's not significantly different from clojure.test. The cljs.test namespace itself has a docstring with updated information. That's the best resource for now. Community updates to the wiki are welcome of course :)

David

On Fri, May 8, 2015 at 2:49 AM, puzzler <mark.en...@gmail.com> wrote:
I can't find any documentation or examples for using the new cljs.test namespace.  Can someone point me in the right direction?  Thanks.

--
Reply all
Reply to author
Forward
0 new messages