-
Notifications
You must be signed in to change notification settings - Fork 150
Conversation
Will fix the style errors asap |
Thanks, this is a great addition. Will review now |
var options = {plugins: {foobar: true}}; | ||
plugins.load(this.gemini, options); | ||
|
||
assert(this.foobarPlugin.calledWith(this.gemini, {})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please use sinon.assert
and js-must
in tests? The rest of the tests are using this assertions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do!
Overall I like the idea of ability to launch webserver, sauceconnect or build tool automatically, but I don't think I see two options here:
What do you think? |
var _this = this; | ||
module.exports = inherit(EventEmitter, { | ||
__constructor: function(config, overrides) { | ||
config = config || DEFAULT_CFG_NAME; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function body should be indented by 4 spaces. Not sure why jshint
didn't notifiy you about it, will check the settings
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I share your concerns - a problem indeed arises with sauce-connect because it needs to finish before running the tests should begin. I thought about it, but originally couldn't find a suitable place in gemini to hook a callback or a promise to it.
So, instead I was planning just to block the execution in the sauce plugin until it's ready - and yes, I'd really rather do it properly :-)
I think I'll start by looking for options on how to do it using promises.
At some point I was considering adding calls before and after calling the gemini.test but dropped the idea afterwards because then it wouldn't work when running tests programmatically using the API, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found something called chained-emitter which seems to do the trick:
var ChainedEmitter = require('chained-emitter').EventEmitter
then, we can do this:
return _this.emit('startRunner', runnerInstance)
.then(function() {
return _this.readTests(paths);
})
.then(function(rootSuite) {
options.reporters.forEach(applyReporter.bind(null, runnerInstance));
return runnerInstance.run(rootSuite);
})
.then(function(data) {
_this.emit('endRunner', runnerInstance, data);
return data;
});
What still bothers me though a bit is the order of the promises.. I would like to emit the 'startRunner' after _this.readTests(paths)
but then we have to rely that the plugins event handler passes through the rootSuite to the next step and making that assumption just doesn't feel right. The same issue is with the 'endRunner' emitter, the 'data' would need to passed through it. Any thoughts on this?
From the plugins perspective, it looks like this currently:
gemini.on('startRunner', function(runner) {
var deferred = Q.defer();
server.start(opts, function(rootUrl) {
gemini.config.rootUrl = rootUrl;
deferred.resolve();
});
return deferred.promise;
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's few ways I achieved the running order I was looking for. They're both ugly, do you know if there is a way to do the same thing with some built-in method found in Q/Promise ?
Nested:
return _this.readTests(paths)
.then(function(rootSuite) {
return _this.emit('startRunner', runnerInstance)
.then(function () {
options.reporters.forEach(applyReporter.bind(null, runnerInstance));
return runnerInstance.run(rootSuite);
});
})
.then(function(data) {
return _this.emit('endRunner', runnerInstance, data)
.then(function() {
return data;
});
});
Using temp vars:
return _this.readTests(paths)
.then(function(rootSuite) {
_this.rootSuite = rootSuite;
})
.then(function() {
return _this.emit('startRunner', runnerInstance);
})
.then(function() {
options.reporters.forEach(applyReporter.bind(null, runnerInstance));
return runnerInstance.run(_this.rootSuite);
})
.then(function(data) {
_this.data = data;
return _this.emit('endRunner', runnerInstance, data);
})
.then(function() {
return _this.data;
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think your first example can be rewritten as:
return _this.readTests(paths)
.then(function(rootSuite) {
return _this.emit('startRunner', runnerInstance).thenResolve(rootSuite);
})
.then(function (rootSuite) {
options.reporters.forEach(applyReporter.bind(null, runnerInstance));
return runnerInstance.run(rootSuite);
})
.then(function(data) {
return _this.emit('endRunner', runnerInstance, data).thenResolve(data)
});
which looks fine to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At some point I was considering adding calls before and after calling the gemini.test but dropped the idea afterwards because then it wouldn't work when running tests programmatically using the API, right?
Yes, you are totally right, if we are adding plugins they should be loaded when using gemini
via API, CLI and GUI
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yes, thenResolve() was exactly what I needed, thanks!
Update: chained-emitter depends on bluebird which apparently doesn't have a thenResolve method.
I guess we'll just have to do a
.then(function() { return rootSuite; });
I'll see if I have time to send a pull request to bluebird at some point.
- Use sinon.assert - Use _.startsWith in resolving packageName. - Refactor pairs usage into a chain.
d56c6be
to
310072a
Compare
@Saulis can you please send |
it('should throw error if plugin not found', function() { | ||
var options = {plugins: {'gemini-foo': true}}; | ||
|
||
try { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it can be written as:
(function() {
plugins.load(this.gemini, options);
}).must.throw()
Overall, it is ready to be merged, but I really want to finish with 0.10.0-final before adding new features. This will take 1-2 days and then I'll merge this PR and publish it as 0.10.1. Are you ok with it? |
@Saulis is away this week, so I’ll provide a comment on his behalf, that 1–2 days delay is totally okay :) |
I might have some time tomorrow to polish things up :) @SevInf yeah I'll make a separate PR, and I'll remove the related changes from this one with a force push |
Sorry for delay, I'm finally done with 0.10. I'm ready to merge this PR, but it needs rebase. Will you do it? |
Sure, just a sec |
- add startRunner and endRunner events. - add chained-emitter to support promises in event handlers.
I had to squash the commits into one to make the merge process easier |
Hmm, I might've screwed something up with the merge, need to check it one more time. Update: nevermind it's good, ready to merge :-) |
Thanks! |
Hi!
Needed to do some plugins for gemini (starting up express, sauce-connect, etc) so I made a really simple plugin loader. What do you think?