Skip to content

Commit

Permalink
feat(runner): allow passing changed/added/removed files
Browse files Browse the repository at this point in the history
This is a feature mostly for WebStorm, which does watch the FS already and so we don't wanna do it twice. WebStorm can pass list of changed files to Karma, so that Karma does not have to re-glob all the patterns.
  • Loading branch information
vojtajina committed Jul 31, 2013
1 parent 081b68c commit b598106
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 6 deletions.
11 changes: 11 additions & 0 deletions lib/cli.js
Expand Up @@ -51,6 +51,17 @@ var processArgs = function(argv, options) {
options.reporters = options.reporters.split(',');
}

if (helper.isString(options.removedFiles)) {
options.removedFiles = options.removedFiles.split(',');
}

if (helper.isString(options.addedFiles)) {
options.addedFiles = options.addedFiles.split(',');
}

if (helper.isString(options.changedFiles)) {
options.changedFiles = options.changedFiles.split(',');
}
options.configFile = path.resolve(argv._.shift() || 'karma.conf.js');

return options;
Expand Down
1 change: 1 addition & 0 deletions lib/helper.js
Expand Up @@ -17,6 +17,7 @@ exports.isDefined = function(value) {
exports.isFunction = _.isFunction;
exports.isString = _.isString;
exports.isObject = _.isObject;
exports.isArray = _.isArray;

var ABS_URL = /^https?:\/\//;
exports.isUrlAbsolute = function(url) {
Expand Down
37 changes: 32 additions & 5 deletions lib/middleware/runner.js
Expand Up @@ -4,6 +4,8 @@
* It basically triggers a test run and streams stdout back.
*/

var path = require('path');
var helper = require('../helper');
var log = require('../logger').create();
var constant = require('../constants');
var json = require('connect').json();
Expand Down Expand Up @@ -43,12 +45,37 @@ var createRunnerMiddleware = function(emitter, fileList, capturedBrowsers, repor
});
});

var clientArgs = request.body.args;
log.debug('Setting client.args to ', clientArgs);
config.client.args = clientArgs;
var data = request.body;
log.debug('Setting client.args to ', data.args);
config.client.args = data.args;

log.debug('Refreshing all the files / patterns');
fileList.refresh();
var fullRefresh = true;

if (helper.isArray(data.changedFiles)) {
data.changedFiles.forEach(function(filepath) {
fileList.changeFile(path.resolve(config.basePath, filepath));
fullRefresh = false;
});
}

if (helper.isArray(data.addedFiles)) {
data.addedFiles.forEach(function(filepath) {
fileList.addFile(path.resolve(config.basePath, filepath));
fullRefresh = false;
});
}

if (helper.isArray(data.removedFiles)) {
data.removedFiles.forEach(function(filepath) {
fileList.removeFile(path.resolve(config.basePath, filepath));
fullRefresh = false;
});
}

if (fullRefresh) {
log.debug('Refreshing all the files / patterns');
fileList.refresh();
}
});
};
};
Expand Down
7 changes: 6 additions & 1 deletion lib/runner.js
Expand Up @@ -58,5 +58,10 @@ exports.run = function(config, done) {
}
});

request.end(JSON.stringify({args: config.clientArgs}));
request.end(JSON.stringify({
args: config.clientArgs,
removedFiles: config.removedFiles,
changedFiles: config.changedFiles,
addedFiles: config.addedFiles
}));
};
12 changes: 12 additions & 0 deletions test/unit/cli.spec.coffee
Expand Up @@ -81,6 +81,18 @@ describe 'cli', ->
expect(options.reporters).to.deep.equal ['dots']


it 'should parse removed/added/changed files to array', ->
options = processArgs [
'--removed-files', 'r1.js,r2.js',
'--changed-files', 'ch1.js,ch2.js',
'--added-files', 'a1.js,a2.js'
]

expect(options.removedFiles).to.deep.equal ['r1.js', 'r2.js']
expect(options.addedFiles).to.deep.equal ['a1.js', 'a2.js']
expect(options.changedFiles).to.deep.equal ['ch1.js', 'ch2.js']


describe 'parseClientArgs', ->
it 'should return arguments after --', ->
args = cli.parseClientArgs ['node', 'karma.js', 'runArg', '--flag', '--', '--foo', '--bar',
Expand Down
37 changes: 37 additions & 0 deletions test/unit/middleware/runner.spec.coffee
Expand Up @@ -11,6 +11,7 @@ describe 'middleware.runner', ->
createRunnerMiddleware = require('../../../lib/middleware/runner').create

handler = nextSpy = response = mockReporter = capturedBrowsers = emitter = config = null
fileListMock = null

beforeEach ->
mockReporter =
Expand All @@ -21,6 +22,10 @@ describe 'middleware.runner', ->
capturedBrowsers = new BrowserCollection emitter
fileListMock =
refresh: -> emitter.emit 'run_start'
addFile: -> null
removeFile: -> null
changeFile: -> null

nextSpy = sinon.spy()
response = new HttpResponseMock
config = {client: {}}
Expand Down Expand Up @@ -73,6 +78,38 @@ describe 'middleware.runner', ->
request.emit 'end'


it 'should refresh explicit files if specified', (done) ->
capturedBrowsers.add new Browser
sinon.stub capturedBrowsers, 'areAllReady', -> true
sinon.stub fileListMock, 'refresh'
sinon.stub fileListMock, 'addFile'
sinon.stub fileListMock, 'changeFile'
sinon.stub fileListMock, 'removeFile'

request = new HttpRequestMock '/__run__', {
'content-type': 'application/json'
'content-length': 1
}
request.setEncoding = -> null

handler request, response, nextSpy
message =
addedFiles: ['/new.js']
removedFiles: ['/foo.js', '/bar.js']
changedFiles: ['/changed.js']

request.emit 'data', JSON.stringify(message)
request.emit 'end'

process.nextTick ->
expect(fileListMock.refresh).not.to.have.been.called
expect(fileListMock.addFile).to.have.been.calledWith '/new.js'
expect(fileListMock.removeFile).to.have.been.calledWith '/foo.js'
expect(fileListMock.removeFile).to.have.been.calledWith '/bar.js'
expect(fileListMock.changeFile).to.have.been.calledWith '/changed.js'
done()


it 'should ignore other urls', (done) ->
handler new HttpRequestMock('/something'), response, ->
expect(response).to.beNotServed()
Expand Down

0 comments on commit b598106

Please sign in to comment.