bensu / doo

doo is a library and lein plugin to run cljs.test on different js environments.
Eclipse Public License 1.0
324 stars 63 forks source link

Unable to run nodejs tests from alternate directory (not root of project) #157

Closed thatismatt closed 6 years ago

thatismatt commented 6 years ago

The working directory for my app is resources/public. I've tried setting :exec-path like this:

:exec-dir (java.io.File. "resources/public")

The result then of calling lein doo node test-id is below (debug is on, you can see the :output-to value in the shell command):

$ lein doo node test-id

;; ======================================================================
;; Testing with Node:

[doo] Command to run script: [node resources/public/test-id.js]
module.js:471
    throw err;
    ^

Error: Cannot find module '/home/matt/my-app/resources/public/resources/public/test-id.js'
    at Function.Module._resolveFilename (module.js:469:15)
    at Function.Module._load (module.js:417:25)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:389:7)
    at startup (bootstrap_node.js:149:9)
    at bootstrap_node.js:504:3
Subprocess failed

If I run node directly in resources/public everything works correctly.

Which looks to me like the :exec-dir config option doesn't account for the location of the :output-to value. I'm aware that the :exec-dir option is undocumented, so I'm happy to be pointed at an alternative way to do this.

I have a workaround where I'm changing the doo path for node:

:doo {:paths {:node "node test-id.js"}
      :exec-dir (java.io.File. "resources/public")}

This works, but obviously is a bit hacky.

Thanks for this great tool, Matt

bensu commented 6 years ago

I don't remember why node struggles with relative/absolute paths. Did you try using :asset-path before :exec-dir?

thatismatt commented 6 years ago

Changing the :asset-path means the test code loads and runs. But this doesn't fix my issue which is that I want the cwd of the node process when running the tests to be "resources/public". My tests depend on this (we verify our config files as part of the tests, arguably this is bad practise, but it is a nice safety check for the CD system).

I know that there were (still are?) issues in compiling cljs to target node, in particular I've hit this issue (https://dev.clojure.org/jira/browse/CLJS-1444) before. But in this case I don't believe this is the fault of the cljs compiler.

So perhaps I should rephrase the bug/feature:

I'd like a way to change the current working directory for the node process that runs the tests. I had assumed that I could do this with :exec-dir. Setting :exec-dir does change the current working directory of the node process, but doesn't change the argument (file name of the test js script, test-id.js in my case) passed to node (in my case doo shells out to node resources/public/test-id.js but because I have set :exec-dir to resources/public this should actually be: node test-id.js

BTW doo is awesome, and I'd be happy to put some effort in to seeing this fixed. I noticed the discussions here: https://github.com/bensu/doo/pull/69 & https://github.com/bensu/doo/pull/77 where you say "We shouldn't expose :exec-dir. As it is right now it is only usable from boot-cljs-test and I can't begin to imagine the edge cases that could arise from other users.", so I am aware that I am straying off the happy path! But if there is anything that I can help with let me know, I'll probably need some pointers though :)

bensu commented 6 years ago

Do you think the expected behavior should be that :exec-dir then adjusts the paths of the scripts?

thatismatt commented 6 years ago

That'd certainly seem intuitive to me.

But I'm happy to be told I'm doing it wrong though! (i.e. that using :exec-dir is the wrong approach.)

On 12 Nov 2017 3:36 a.m., "Sebastian Bensusan" notifications@github.com wrote:

Do you think the expected behavior should be that :exec-dir then adjusts the paths of the scripts?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/bensu/doo/issues/157#issuecomment-343711082, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEuSEHaSjfHKfoK0UV_3JOm1Yu19iSRks5s1meqgaJpZM4QU44D .

bensu commented 6 years ago

The problem with adjusting the path of the file to be run is that the rest of the paths (internally generated by cljs) will not be updated and that type of inconsistency is hard to resolve. Also, I suspect that changing that behavior would break boot-cljs-test so I wouldn't recommend it.

If you want to try something less hacky, you can do :path "cd resources/public && node" If that works, great. Otherwise, I'm out of ideas :)

thatismatt commented 6 years ago

Thanks @bensu

For others finding this in the future, here is my final solution:

In project.clj I point at a custom script:

:doo {:paths {:node "scripts/node-doo.sh"}}

The content of the script node-doo.sh:

#!/bin/bash

TEST_FILE=$(readlink -e $1)
cd resources/public
node $TEST_FILE

The end result of all this is that node is invoked with a filename that works (a fully qualified one in this case) and the cwd is resources/public.

Finally, it should be noted that :path "cd resources/public && node" won't work because cd isn't a command it is a builtin (which is why I used a bash script instead).

bensu commented 6 years ago

Great, thanks for documenting the solution!