Skip to content

cemerick.cljs.test was not required...even though it was? #68

Closed
venantius opened this Issue Jun 9, 2014 · 22 comments

9 participants

@venantius

I've been tinkering with this all afternoon and am not getting anywhere, so here I come to the internets. My test namespace sits at ./test/cljs/circleci/test_git.cljs (note the :require and :require-macros, basically copy-pasted from the README):

(ns circleci.test-git
  (:require-macros [cemerick.cljs.test
                    :refer (is deftest with-test run-tests testing test-var)])
  (:require [cemerick.cljs.test :as t]
            [cljs.nodejs :as node]))

(deftest somewhat-less-wat
  (is (= "{}[]" (+ {} []))))

What I get out of trying to do lein cljsbuild test:
ERROR: cemerick.cljs.test was not required.

I thought for a while that I just must have been screwing up my project.clj (which could very well still be possible)...here are the relevant bits:

  :dependencies [[org.clojure/clojurescript "0.0-2156"]]

  :plugins [[com.cemerick/clojurescript.test "0.3.1"]
            [lein-cljsbuild "1.0.2"]
            [lein-npm "0.4.0"]]
  :hooks [leiningen.cljsbuild]
  :node-dependencies [[request "2.36.0"]
                      [docopt "0.4.0"]
                      [git "0.1.5" ]]
  :source-paths ["src/cljs" "test/cljs"]
  :test-paths ["test/cljs"]
  :cljsbuild {:builds [{:id "main"
                        :source-paths ["src/cljs"]
                        :compiler {:output-to "out/circleci.js"
                                   :optimizations :simple
                                   :target :nodejs
                                   :pretty-print true}}
                       {:id "test"
                        :source-paths ["test/cljs"]
                        :compiler {:output-to "out/circleci-test.js"
                                   :optimizations :simple
                                   :target :nodejs
                                   }}]
              :test-commands {"unit-tests" ["node" :node-runner
                                            "out/circleci-test.js"]}})

What confuses me is that when I look into circleci-test.js I can see what I assume to be the necessary definitions, e.g.:

var cemerick = {cljs:{}};
cemerick.cljs.test = {};
cemerick.cljs.test._STAR_test_print_fn_STAR_ = null;
cemerick.cljs.test._STAR_entry_point_STAR_ = !0;
cemerick.cljs.test._STAR_test_ctx_STAR_ = null;
cemerick.cljs.test.init_test_environment_STAR_ = function(a) {
  return cljs.core.atom.call(null, cljs.core.merge.call(null, cljs.core.assoc.call(null, cljs.core.merge.call(null, new cljs.core.PersistentArrayMap(null, 4, [new cljs.core.Keyword(null, "test", "test", 1017460740), 0, new cljs.core.Keyword(null, "pass", "pass", 1017337731), 0, new cljs.core.Keyword(null, "fail", "fail", 1017039504), 0, new cljs.core.Keyword(null, "error", "error", 1110689146), 0], null), cljs.core.truth_(cemerick.cljs.test._STAR_test_print_fn_STAR_) ? new cljs.core.PersistentArrayMap(null, 
  1, [new cljs.core.Keyword("cemerick.cljs.test", "test-print-fn", "cemerick.cljs.test/test-print-fn", 740963180), cemerick.cljs.test._STAR_test_print_fn_STAR_], null) : null), new cljs.core.Keyword("cemerick.cljs.test", "test-contexts", "cemerick.cljs.test/test-contexts", 1853176376), cljs.core.List.EMPTY), a));
};

...(lots more where that came from)

So I'm not really sure what's being done wrong here. Any thoughts?

@venantius

I pushed my version back to 0.3.0 and that gets me the perhaps-more-perhaps-less confusing stacktrace of:

/private/var/folders/7y/rh80w5_57p3d9tqvgj3x_clh0000gn/T/node-runner1823545305759259480.js:26
cemerick.cljs.test.set_print_fn_BANG_(function(x) {
^
ReferenceError: cemerick is not defined
    at Object.<anonymous> (/private/var/folders/7y/rh80w5_57p3d9tqvgj3x_clh0000gn/T/node-runner1823545305759259480.js:26:1)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:902:3
Subprocess failed

I'd normally guess that lein-cljsbuild wasn't picking up my test files, but I can see that the compiled JS has both the namespace and the particular dummy test in there as well:

cemerick.cljs.test.register_test_BANG_.call(null, new cljs.core.Symbol(null, "circleci.test-git", "circleci.test-git", -2147236984, null), new cljs.core.Symbol("circleci.test-git", "somewhat-less-wat", "circleci.test-git/somewhat-less-wat", -76443432, null), circleci.test_git.somewhat_less_wat);
@bbbates
bbbates commented Jun 12, 2014

+1 for this as well. Happens with both phantomjs and node runners.

@cemerick
Owner

@venantius any chance you can push a sample project that demonstrates this behaviour to a repo somewhere?

@venantius

@cemerick I've pulled out the guts and left a skeleton outlining my problem that you should be able to find here https://github.com/venantius/cli-test

@cemerick
Owner

Thanks, will take a look shortly.

@cemerick cemerick added this to the 0.3.2 milestone Jun 24, 2014
@spiralman

FYI, I'm running into this problem too. I haven't completely debugged the issue, but I feel like it might be related to relative paths (Note: assumes project.clj configures the test build :output-dir "test-out"):

When I copy/paste the examples from the README, I get an error like this (before the warning about cemerick.cljs.test not being required):

ReferenceError: Can't find variable: goog

  test-output.js:1

If I then add test-out/goog/base.js to my test command (after :runner before test-output.js), that error goes away. If I then add test-out/cemerick/cljs/test.js, I start running into other dependency errors; as I manually add the required output files, the errors go away, but more are created. I haven't tried adding every single dependency in the order that it's needed, but I assume it would eventually work.

My guess is that however Google Closure is loading dependencies doesn't quite work with PhantomJS. I feel like I might have run into a problem like this before on a straight JavaScript project (that used RequireJS, not Closure), and that the problem was that PhantomJS resolves relative paths in a slightly strange way, but don't remember what the solution was.

I think it involved re-configuring RequireJS with a custom module base path that fixed the differences between PhantomJS on the command line and a browser evaluating an HTML file from a server.

@spiralman

Looks like I spoke too soon: I was using :optimizations :none, but switching that to :optimizations :whitespace solved the problem, since it concatenates everything into a single source file.

Maybe :simple also maintains separate files, which is what's causing problems for @venantius ?

@mijoharas

Any word on this? I have the same problem, are there any workarounds?

@mijoharas

hmmm... This does work for me, but for me the problem wasn't to do with :optimisations :none as it also didn't work with :optimisations :whitespace I'll have to look into this closely and try and figure out why this works and my version does not.

@peterschwarz

The node js compilation adds #!/usr/bin/env node to the top of the compiled files. Not sure why this is the default, but somewhere around this commit. (?)

Add :hashbang false to your compiler options for your test code. Should fix things.

@jplaza
jplaza commented Sep 25, 2014

I'm having the same issue here, but only when including additional namespaces

Tests run if I use:

(ns my.project.test
  (:require-macros [cemerick.cljs.test
                    :refer (is deftest with-test run-tests testing test-var)])
  (:require [cemerick.cljs.test :as t])

But I get ERROR: cemerick.cljs.test was not required. if I include a new namespace that's part of my src

(ns my.project.test
  (:require-macros [cemerick.cljs.test
                    :refer (is deftest with-test run-tests testing test-var)])
  (:require [cemerick.cljs.test :as t]
            [my.project.impl :as m])
@chadharrington

We have this problem when we switch from the phantomjs runner to the nodejs runner. Tests work fine under phantom, fail under node with:
ERROR: cemerick.cljs.test was not required.

Here is a minimal-ish failing test case:
https://github.com/farbetter/testtest

Thanks!

@mike-thompson-day8

@chadharrington Hmm. I notice is that you don't have :target :nodejs in your project.clj :compile spec. And you haven't set *main-cli-fn*

There may be other problems too. Unfortunately, the runner seems to currently swallow all meaningful errors and replace them with the message you saw (which is obviously not helpful).

You might find this helpful: https://github.com/mike-thompson-day8/cljsbuild-none-test-seed

@chadharrington

@mike-thompson-day8 Thanks for your interest. Your comments made me realize that I hadn't illustrated the two approaches (phantom & node) clearly. I updated the repo to show the problem using lein aliases and a better README. I also removed some potentially confusing extra code. The core problem is that the same tests run w/ phantom but not with node.

If you see anything obviously wrong in the updated repo (v0.1.1), please let me now.

@mike-thompson-day8

It good that you have added :target :nodejs. That will help.

But what about my 2nd recommendation about setting *main-cli-fn* ?
https://github.com/clojure/clojurescript/wiki/Quick-Start#running-clojurescript-on-nodejs

Other than that, please just look at the repo I supplied. It works.

@chadharrington

@mike-thompson-day8 In order to be more clear, I simply removed all printing from the main source file. This removes the need for setting *main-cli-fn*, which works for node, but not phantom. The repo, as it stands, is about as minimal a test case as I can muster for this bug.

I did look at your repo yesterday as a possible workaround and filed an issue on it. I found that tests were passing when they should fail. I am interested to see if you can reproduce that issue.

Thanks again for your interest.

@chadharrington

@mike-thompson-day8 I added setting *main-cli-fn* to the repo; it seems to have no effect on the situation.

$ lein test-phantom
Deleting files generated by lein-cljsbuild.
Compiling ClojureScript.
Compiling "target/test/phantom/testtest_test.js" from ["src" "test"]...
Successfully compiled "target/test/phantom/testtest_test.js" in 11.53 seconds.
Compiling "target/test/node/testtest_test.js" from ["src" "test"]...
Successfully compiled "target/test/node/testtest_test.js" in 9.523 seconds.
Running ClojureScript test: phantom-test

Testing testtest.test-core 

Ran 2 tests containing 2 assertions.
Testing complete: 0 failures, 0 errors.

Ran 2 tests containing 2 assertions.
Testing complete: 0 failures, 0 errors.

$ lein test-node
Deleting files generated by lein-cljsbuild.
Compiling ClojureScript.
Compiling "target/test/phantom/testtest_test.js" from ["src" "test"]...
Successfully compiled "target/test/phantom/testtest_test.js" in 11.713 seconds.
Compiling "target/test/node/testtest_test.js" from ["src" "test"]...
Successfully compiled "target/test/node/testtest_test.js" in 10.502 seconds.
Running ClojureScript test: node-test

ERROR: cemerick.cljs.test was not required.

You can resolve this issue by ensuring [cemerick.cljs.test] appears
in the :require clause of your test suite namespaces.
Also make sure that your build has actually included any test files.

Also remember that Node.js can be only used with simple/advanced 
optimizations, not with none/whitespace.

Subprocess failed
$
@peterschwarz

@chadharrington You can workaround this by adding :hashbang false to your cljsbuild node configuration:

"node" {:source-paths ["src" "test"]
        :compiler
        {:output-to "target/test/node/testtest_test.js"
         :output-dir "target/test/node"
         :optimizations :simple
         :hashbang false
         :target :nodejs}}

With out this, the generated js file has
#!/usr/bin/env node
In it's first line. This is not valid js, so it doesn't run.

@chadharrington

@peterschwarz That solved it! Thank you very much. I updated the repo (https://github.com/farbetter/testtest) with the working solution, in case anyone is following along at home. It's frustrating that the error message given had nothing to do with the actual problem. I think the real issue here is that the ERROR: cemerick.cljs.test was not required. message eats other, unrelated, errors.

@peterschwarz

There are a couple of pull requests out there (#74, #76) to help give proper error messages.

@cemerick
Owner

Interesting, I've not used :target :nodejs for any of my node-targeted compilations. In fact, removing that from @venantius' original test repo's project.clj eliminates the error.

I've merged #74, which should help in diagnosing things like this.

@cemerick cemerick closed this Dec 11, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.