crisptrutski/boot-cljs-test

Confusing error around `cljs.test` not being defined

crisptrutski opened this issue Β· 15 comments

see boot-clj/boot#277

hi @hellonico πŸ‘‹ πŸ˜„

the message you've pasted is pretty opaque, and means that the script which ends up executing your tests is not loading the code correctly.

to give a quick overview of how this libraries is used by tenzing, the test-cljs task does the following:

  1. create runner namespace which instruments and executes all tests
  2. create compiled-js-for-tests-and-code.js
  3. execute (2) in correct environment, with appropriate shims, and appropriate reporting

the error you're seeing is occuring in (3)

so what could go wrong?

  1. the js may have failed to compile
  2. the compiled js may have errors (eg see http://dev.clojure.org/jira/browse/CLJS-1399 where emitted js is not valid and will not execute)
  3. the compiled code may break in the environment (eg. shim is not strong enough)
  4. the particular runner may have a bug when combined with relative paths, given optimization level, or even the combination (eg. rhino)

Happily doo will soon improve to provide better diagnostic messages (see bensu/doo#21), to tell these cases apart

things to try:

  1. use another javascript environment (eg slimer, phantom)
  2. use another optimization level (eg whitespace)
  3. upgrading to latest snapshot of boot-cljs-test

if you can provide more details here or even a reproducing repo, i'd be glad to help you debug further.

@martinklepsch we should probably cut a release to get martinklepsch/tenzing#40 out, as i think the old defaults are probably the issue

@crisptrutski done. 0.3.3 is released. I was actually just investigating the same thing :D

0.3.4 also has the proper :js-env default setting :)

indeed. create a new project using the new template and ... some awesomeness happened. Perfect.

should we close this?

@martinklepsch let's wait until the error messages are improved

From my track record so far, unless others step in I won't get around to polishing the "UI" aspect of this project. In anycase there are bigger warts with the console output (no verbosity control, noise seeping out of some environments (eg. phantomjs Unsafe JavaScript attempt to access frame), inconsistent line spacing, etc.

Contributions welcome in this area, but closing as nothing planned

I feel like my issue is related to this, so I'm going to tack on here instead of open a new one. I just cannot get my boot-cljs-test task to run unless I provide at least level 1 :whitespace optimization. I went round and round for a while until trying out :advanced and stepping down to :whitespace. There is something about :none that just doesn't work, and I always get this error:

Running cljs tests...ClojureScript could not load :main, did you forget to specify :asset-path?

ERROR: doo was not loaded from the compiled script.

Make sure you start your tests using doo-tests or doo-all-tests
and that you include that file in your build

It turns out, when running with :whitespace, some compilation errors (bad var ref, bad namespace) are illuminated whereas :none hides all those errors under the blanket message posted above.

Any thoughts on why :none just doesn't run the tests?

@aft-luke You may be experiencing an issue with relative paths - :none compiles separate js files that must be loaded from the entry point, while the other levels create a single file without any dynamic loading.

Have I missed another issue where you're giving more context about the issue's your experiencing? A reference repo would be ideal to poke at.

Here's potentially the problem, thought I'm not quite sure how to fix it. As you mentioned, :none doesn't compile everything down into one runnable main.js. Instead, the main.js looks like this:

var CLOSURE_UNCOMPILED_DEFINES = null;
if(typeof goog == "undefined") document.write('<script src="main.out/goog/base.js"></script>');
document.write('<script src="main.out/cljs_deps.js"></script>');
document.write('<script>if (typeof goog != "undefined") { goog.require("boot.cljs.main18024"); } else { console.warn("ClojureScript could not load :main, did you forget to specify :asset-path?"); };</script>');

The magic happens inside goog.require("boot.cljs.main18024");, where this serves as the bootstrap to load up the rest of the separate files. Surely there must be a way to use phantomjs to read-in this main.js file and hook into it to pull in the required files?

Confirmed @crisptrutski that's indeed the problem. I found some interesting experiments https://github.com/mike-thompson-day8/cljsbuild-none-test-seed/blob/master/project.clj with regards to loading up relative paths using the private closure api. Risky business, but it's worth it to me to have my tests be near-instant, instead of :whitespace optimized on a ~3-10 second delay.

@aft-luke The work around I've taken with this has been to pass a hacky :exec-dir parameter down to doo to force the correct relative URL. This should happen automatically for all boot-cljs-test builds, and thus I've been happily testing projects with :none (it's the default, and how boot-cljs-test tests itself on CI too)

Not sure why it's broken in your case - but would happily look at a project where you're reproducing the issue.

In your last comment it sounds like you're suggesting generating our own entry point which uses absolute file paths for the script?

That is an interesting approach, and would be quite powerful for adding better errors, and just fix the relative url issue at the source (replace with absolute) . Gosh darn hacky, but would consider such a PR πŸ˜„

On top of the better error handling, generating your own entry point also provides full control over the testing output (it's just html/css). One can make the test results much easier to read by pulling it out of the terminal and serving at localhost:port/test.html.

Since cljs.test supports extensible reporters, wouldn't need these pre-emptive hyginx for that last suggestion. That sounds like a nice plugin - could even trigger a browser refresh via web socket.

That’s exactly what I have setup via boot-reload and a simple js-onreload callback.

On May 2, 2016, at 2:48 PM, Chris Truter notifications@github.com wrote:

Since cljs.test supports extensible reporters, wouldn't need pre-emptive for that last part. That sounds like a nice plugin - could even trigger a browser refresh via web socket.

β€”
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub #14 (comment)