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

Node.js-style --require CLI argument #296

Merged
merged 1 commit into from
Dec 11, 2015
Merged

Node.js-style --require CLI argument #296

merged 1 commit into from
Dec 11, 2015

Conversation

jokeyrhyme
Copy link
Contributor

I figured I'd have an attempt at being able to pass the --require through to the Node executable used for the child process (#229).

My test project uses import and export, so doesn't execute in Node v5 without babel/register. I can manually confirm using npm link that the changes I have so far function as expected.

Besides general comments (very much appreciated), I'm a little bit at a loss as where to start with the tests. Do I need to confirm (with tests) that the ava --require moduleId works? Or is it sufficient to use mocks and confirm that arguments are being passed through as expected?

@jokeyrhyme jokeyrhyme changed the title WIP: ava --require babel/register works (needs tests) WIP: ava --require babel/register works Dec 3, 2015
@jamestalmage
Copy link
Contributor

Do I need to confirm (with tests) that the ava --require moduleId works?

That would be my approach, does not need to be fancy.

// test/fixture/install-global.js

global.foo = 'bar'
// test/fixture/validate-installed-global.js

import test from '../../'

test(t => t.is(global.foo, 'bar'));

Then use the API to call validate-... using the require hook you've just implemented.

Overall looks pretty good.

return fork(args)
var options = {};

if (Array.isArray(this.require) && this.require.length) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just do

if (this.require) {
 // ...
}

You have already guaranteed it is an array of at least length one above.

@sindresorhus
Copy link
Member

Not sure we ever got an agreement on this:

Would exposing the Node.js binary --require flag while disabling our Babel hook solve your problem

@jamestalmage ^

@jamestalmage
Copy link
Contributor

I don't know if our Babel hook should be disabled automatically. I still have not decided the best way to make it all work.

My current thinking is using something along the lines of #297, but using a better version of istanbul-lib-hook. https://github.com/jamestalmage/transform-chain would be part of it. Combine transform-chain with a way of detecting when hooks are installed, similar to how @novemberborn did it here in nyc.

@jokeyrhyme
Copy link
Contributor Author

Unless I somehow accomplished this accidentally, I did not attempt to disable ava's babel hook. My only purpose with this PR was the pass through the --require.

Also, I hope to get time to address the PR feedback over the next few days. I'm sorry for not being very responsive.

@jamestalmage
Copy link
Contributor

Unless I somehow accomplished this accidentally, I did not attempt to disable ava's babel hook

Understood, we are still deciding if / when / how to do that. Once a decision on that gets made we will merge this, and augment it with whatever behavior we finally decide on.

I'm sorry for not being very responsive.

That is not a problem. We still have to answer a few questions, so we are in no rush to merge.

@jokeyrhyme jokeyrhyme changed the title WIP: ava --require babel/register works WIP: pass --require through to Node.js exec Dec 5, 2015
@jokeyrhyme
Copy link
Contributor Author

I still haven't pushed tests yet. They don't seem quite as trivial as I'd hoped, even with @jamestalmage's suggestions. Soon...

@jokeyrhyme
Copy link
Contributor Author

Really stuck with the testing part. I'm getting similar errors when I try to use api.js instead of cli.js.

I've tried a few simple approaches, and none of them work. But this functionality doesn't seem complicated enough to warrant a complicated test. Is there an obvious flaw in this approach? Or do I need to take this up a notch?

@jokeyrhyme
Copy link
Contributor Author

Thanks for the hint, @jamestalmage. At least now, the errors are all the same one:

Test files must be run with the AVA CLI

@jokeyrhyme
Copy link
Contributor Author

I could use mockery and just confirm that Node.js is called with the expected parameters, without actually calling Node.js? /shrug

@jamestalmage
Copy link
Contributor

Well, I'm having a hard time getting this to work on travis. Test #4 seems to work on OSX. Note that the --require flag does not work on Node <4

@jamestalmage
Copy link
Contributor

@sindresorhus @vdemedes - either of you develop on linux? Any advice on how he should fix this?

@jokeyrhyme
Copy link
Contributor Author

So I should detect the version of Node in the tests and only run them for >=4.0?
And there's still something funny going on with the paths. The fact that it's so hard to test properly makes me wonder if I've taken a good approach in the first place. :S

@jamestalmage
Copy link
Contributor

I don't know. Maybe it would just be better to manually implement the same semantics as the --require flag ourselves. You could just do require(somePath), for every --require== flag inside babel.js. Might end up being more reliable.

@sindresorhus
Copy link
Member

either of you develop on linux? Any advice on how he should fix this?

I have Linux in a VM, but I almost never use it, so pretty noobish with it.

Maybe it would just be better to manually implement the same semantics as the --require flag ourselves.

👍 This is where the --require magic happens: https://github.com/nodejs/node/blob/04b1a2f7564d70dfdab838d2830e04af34b97fe6/lib/module.js#L469-L488 Which is pretty much just require(resolveCwd(cli.flags.require)); (we already depend on resolve-cwd)

@jokeyrhyme
Copy link
Contributor Author

Okay, well I'll have another crack at it over the next few days. I'll try implementing --require internally so that it works regardless of the Node.js version.

if (this.require && !Array.isArray(this.require)) {
// normalise single `--require moduleId` usage
this.require = [this.require];
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just use arrify on line 69 and drop this whole thing.

@sindresorhus
Copy link
Member

requires.forEach(function (el) {
  require(resolveCwd(el));
));

@@ -0,0 +1 @@
global.foo = 'bar'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

semicolon

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Weird. I love my semi-colons, too. I wonder why ESLint didn't bust my chops about this? :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jokeyrhyme
Copy link
Contributor Author

Also, I added 4 tests to check different argument orders, but we should probably just pick the one we like and get rid of the rest?

@@ -16,6 +16,11 @@ if (debug.enabled) {
// Bind globals first, before anything has a chance to interfere.
var globals = require('./globals');

var resolveCwd = require('resolve-cwd');
(opts.require || []).forEach(function (moduleId) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think opts.require is already guaranteed to be an array, so this check is moot.

https://github.com/sindresorhus/ava/pull/296/files#diff-2cce40143051e25f811b56c79d619bf5R73

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope. In the API tests, new Api() is called without the second parameter, which means it ends up being an empty Object, without a "require" property. Should I change the fallback default value in api.js to include an empty "require" array? e.g. this.options = options || { require: [] }; ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, never mind then. I read it wrong.

@jokeyrhyme
Copy link
Contributor Author

Okay, so in total I have 1 api test and 1 cli test. I left the cli test in there to stress the end-to-end process a bit. Of course, if you think this is overkill then I'm happy to drop the cli test completely.

@@ -697,4 +698,3 @@ Concurrency is not parallelism. It enables parallelism. [Learn more.](http://sta
<br>
<br>
</div>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't remove

@sindresorhus
Copy link
Member

I left the cli test in there to stress the end-to-end process a bit

I think it's overkill to CLI test all options, but I'm ok with this if you rework it into being a generic CLI option test, meaning change the test description. We should have one CLI test making sure options are passed correctly.

@jokeyrhyme
Copy link
Contributor Author

I gave it a whirl, but it seemed infeasible to mock the boundary from cli.js to the others, and my other approach to CLI argument tests seemed unnecessarily complex (and still didn't work).

If we still feel strongly about having CLI tests, we can have a separate Issue / PR.

@sindresorhus
Copy link
Member

LGTM

1 similar comment
@vadimdemedes
Copy link
Contributor

LGTM

sindresorhus added a commit that referenced this pull request Dec 11, 2015
Node.js-style --require CLI argument
@sindresorhus sindresorhus merged commit d5b25f2 into avajs:master Dec 11, 2015
@sindresorhus
Copy link
Member

Thank you @jokeyrhyme! :) 💥👌

Keep the quality contributions coming. We really appreciate your help.

@vadimdemedes
Copy link
Contributor

Thank you for your work, @jokeyrhyme!

@jokeyrhyme jokeyrhyme deleted the pass-through-requires branch December 11, 2015 20:05
@ariporad
Copy link
Contributor

Hey, @sindresorhus, @vdemedes, @jamestalmage: Any idea when this might ship? I'd really prefer to not depend directly on master. Thanks!

@sindresorhus
Copy link
Member

@ariporad We're planning a new release when #326 lands.

@ariporad
Copy link
Contributor

Thanks @sindresorhus!

@sindresorhus
Copy link
Member

@ariporad Actually, I did a release now. https://github.com/sindresorhus/ava/releases/tag/v0.8.0

@ariporad
Copy link
Contributor

Yay! Thanks!

@jamestalmage
Copy link
Contributor

Any idea why Mocha would be outperforming AVA by such a huge factor, in that case? Are there existing perf issues that you're aware of? (Sorry, not directly related to this PR)

@billyjanitsch

There have been major performance improvements since this was discussed. If possible, could you give AVA a try again and tell us how we're doing?

@billyjanitsch
Copy link
Contributor

@jamestalmage

That's great to hear!

Currently this is the biggest migration blocker for us: it's important that our tests run in the same transpilation environment as our lib code (we now use several custom Babel transforms). Our test suite is large enough (>100 files) that I'd rather not rewrite it in AVA until I know this will be possible.

That said, I'd be happy to convert a couple of our tests to see what the perf looks like relative to Mocha.

@novemberborn
Copy link
Member

@billyjanitsch

Currently this is the biggest migration blocker for us: it's important that our tests run in the same transpilation environment as our lib code (we now use several custom Babel transforms).

My approach to this is to transpile using babel-cli and run the tests on the transpiled code as it sits on the disk. That way I know that I'm testing the code that I'll end up publishing.

See identifierfy for an example.

@jamestalmage
Copy link
Contributor

Our test suite is large enough (>100 files) ...

Wow! I would love to see a project that big converted. Is it open source? What is your current test setup? (mocha with chai for assertions, etc)

You may also want to wait for customizable assertions, so we can create one that matches your current assertion api exactly.

@billyjanitsch
Copy link
Contributor

@novemberborn

My approach to this is to transpile using babel-cli and run the tests on the transpiled code as it sits on the disk.

I think you're talking about transpiling lib code (imported by tests). This PR provides an easier way to do that: --require 'babel-core/register'.

I'm talking about having test code transpiled in the same way that your lib code is, rather than letting AVA transpile it. See the comment that I linked to for more info.

@jamestalmage

Is it open source? What is your current test setup?

Unfortunately not. I work on Kensho's front-end and we're currently using Mocha/Chai (assert style). I'd like to move to a flat Tape/AVA-style interface.

We do have an open source React chart lib -- also using Mocha but faking a Tape-ish API -- that we might be able to convert as well.

You may also want to wait for customizable assertions, so we can create one that matches your current assertion api exactly.

I'm actually not a huge fan of our current assertions, so I don't mind rewriting them when the time comes. AVA's defaults seem great.

@jamestalmage
Copy link
Contributor

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

Successfully merging this pull request may close these issues.

7 participants