Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Require failure using wallaby_server with wallaby and coffeescript #52

Open
jdrucza opened this issue Jul 19, 2016 · 4 comments
Open

Require failure using wallaby_server with wallaby and coffeescript #52

jdrucza opened this issue Jul 19, 2016 · 4 comments

Comments

@jdrucza
Copy link

jdrucza commented Jul 19, 2016

I'm trying to get wallaby working for server tests for a meteor app that uses coffeescript. So I tried to use the wallaby_server file from this repo however it fails because it can't find any meteor modules/packages. It also fails to load local modules referenced by absolute path or with the extension '.coffee'. The last is totally acceptable and the requirement for relative paths is manageable if necessary but obviously the failure to load meteor packages is a show stopper.

Sample project demonstrating the issue: https://github.com/jdrucza/coffee-wallaby

NOTE: I renamed the wallaby_server.js to '.wallaby_server.js' (i.e. starting with a '.') so it would not be picked up by meteor.

Probably obvious but for completeness/search-aid the error is:

wallaby.js started
core v1.0.259
Runtime error: Error: Cannot find module 'meteor/meteor'
    at Function.Module._resolveFilename (module.js:338:15)
    at Function.Module._load (module.js:280:25)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at Object.<anonymous> (./imports/testSetup.spec.js:5:26)
....

I suspect the issue may be that wallaby needs to be configured to use meteor's coffeescript rather than its in-built version but I've no idea how to make this happen.

@ghost
Copy link

ghost commented Jul 29, 2016

This is indeed a limitation of the current implementation.

I think a reasonable solution would be to make the Node.js require aware of the Meteor packages by adding them to require.cache.

E.g.

const meteorRequire = meteorInstall();
require.cache['meteor/meteor'] = meteorRequire('meteor/meteor');

@jdrucza
Copy link
Author

jdrucza commented Jul 30, 2016

Seemed like a good suggestion except it doesn't work because the cache key is the resolved filename not the string identifying the module.
So I tried to replace require.resolve with a function that would resolve anything starting with 'meteor' to the module name and pass everything else through but it seems that require doesn't actually use require.resolve, rather they both use Function.Module._resolveFilename but I haven't yet found a way to override this... any further suggestions?

At the moment I am going to try overriding or replacing 'require' with one that uses meteorRequire directly when possible.

@ghost
Copy link

ghost commented Jul 30, 2016

Another approach would be to use proxyquire in the test files:

const meteorRequire = meteorInstall();
const proxyquire = require('proxyquire');

const stubs = {
  // meteor/meteor is not available in our testing environment, so we need `'@noCallThru': true`
  '@noCallThru': true,
  'meteor/meteor': meteorRequire('meteor/meteor')
};

proxyquire('./unit_under_test', stubs);

And yet another approach maybe is to load the app files that were compiled by the Meteor build tool by removing https://github.com/xolvio/automated-testing-best-practices/blob/master/wallaby_server.js#L235-L238 and using meteorRequire in your tests.

const meteorRequire = meteorInstall();
const unitUnderTest = meteorRequire('./unit_under_test');

@jdrucza
Copy link
Author

jdrucza commented Aug 2, 2016

Thanks for the suggestions. I ended up going with a solution that replaced the use of require for all non-relative-path require statements with a function from an imported module at the root of the app that conditionally used meteorRequire, not ideal but solved a couple of require related challenges and is a fairly easy search and replace refactor if and when possible.

This worked well until trying to execute tests that involved running code from the meteor packages (the primary goal) which resulted in: "before all" hook: Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment. because the before all contained resetDatabase() from xolvio cleaner. I tried the suggestion but then the test itself reported the same fiber related issue.

Is it correct and necessary to call Meteor.bindEnvironment for every describe / it / before block and if so will this also work when running under meteor test? Am I missing something else, like is there a way/need to tell wallaby to use the dispatch:mocha-phantomjs installation rather than its own mocha?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant