Skip to content

Commit

Permalink
refactor: split up the client code, use commonjs
Browse files Browse the repository at this point in the history
  • Loading branch information
vojtajina committed Aug 27, 2013
1 parent bbc63e7 commit 1bd50e0
Show file tree
Hide file tree
Showing 14 changed files with 231 additions and 223 deletions.
12 changes: 8 additions & 4 deletions Gruntfile.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ module.exports = (grunt) ->

files:
server: ['lib/**/*.js']
client: ['static/karma.src.js']
client: ['client/**/*.js']
grunt: ['grunt.js', 'tasks/*.js']
scripts: ['scripts/*.js']

build:
client: '<%= files.client %>'
browserify:
client:
files:
'static/karma.js': ['client/main.js']

test:
unit: 'simplemocha:unit'
Expand All @@ -35,7 +37,7 @@ module.exports = (grunt) ->
watch:
client:
files: '<%= files.client %>'
tasks: 'build:client'
tasks: 'browserify:client'


simplemocha:
Expand Down Expand Up @@ -127,7 +129,9 @@ module.exports = (grunt) ->
grunt.loadNpmTasks 'grunt-npm'
grunt.loadNpmTasks 'grunt-auto-release'
grunt.loadNpmTasks 'grunt-conventional-changelog'
grunt.loadNpmTasks 'grunt-browserify'

grunt.registerTask 'build', ['browserify:client']
grunt.registerTask 'default', ['build', 'test', 'lint']
grunt.registerTask 'lint', ['jshint', 'coffeelint']
grunt.registerTask 'release', 'Build, bump and publish to NPM.', (type) ->
Expand Down
5 changes: 5 additions & 0 deletions client/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
VERSION: '%KARMA_VERSION%',
KARMA_URL_ROOT: '%KARMA_URL_ROOT%',
CONTEXT_URL: 'context.html'
};
119 changes: 12 additions & 107 deletions static/karma.src.js → client/karma.js
Original file line number Diff line number Diff line change
@@ -1,63 +1,20 @@
var CONTEXT_URL = 'context.html';
var VERSION = '%KARMA_VERSION%';
var KARMA_URL_ROOT = '%KARMA_URL_ROOT%';

// connect socket.io
// https://github.com/LearnBoost/Socket.IO/wiki/Configuring-Socket.IO
var socket = io.connect('http://' + location.host, {
'reconnection delay': 500,
'reconnection limit': 2000,
'resource': KARMA_URL_ROOT.substr(1) + 'socket.io',
'sync disconnect on unload': true,
'max reconnection attempts': Infinity
});

var browsersElement = document.getElementById('browsers');
socket.on('info', function(browsers) {
var items = [], status;
for (var i = 0; i < browsers.length; i++) {
status = browsers[i].isReady ? 'idle' : 'executing';
items.push('<li class="' + status + '">' + browsers[i].name + ' is ' + status + '</li>');
}
browsersElement.innerHTML = items.join('\n');
});
socket.on('disconnect', function() {
browsersElement.innerHTML = '';
});

var titleElement = document.getElementById('title');
var bannerElement = document.getElementById('banner');
var updateStatus = function(status) {
return function(param) {
var paramStatus = param ? status.replace('$', param) : status;
titleElement.innerHTML = 'Karma v' + VERSION + ' - ' + paramStatus;
bannerElement.className = status === 'connected' ? 'online' : 'offline';
};
};
var stringify = require('./stringify');
var constant = require('./constants');
var util = require('./util');

socket.on('connect', updateStatus('connected'));
socket.on('disconnect', updateStatus('disconnected'));
socket.on('reconnecting', updateStatus('reconnecting in $ ms...'));
socket.on('reconnect', updateStatus('re-connected'));
socket.on('reconnect_failed', updateStatus('failed to reconnect'));

var instanceOf = function(value, constructorName) {
return Object.prototype.toString.apply(value) === '[object ' + constructorName + ']';
};

/* jshint unused: false */
var Karma = function(socket, context, navigator, location) {
var hasError = false;
var startEmitted = false;
var store = {};
var self = this;
var browserId = (location.search.match(/\?id=(.*)/) || [])[1] ||
'manual-' + Math.floor(Math.random() * 10000);
var browserId = (location.search.match(/\?id=(.*)/) || [])[1] || util.generateId('manual-');

var resultsBufferLimit = 1;
var resultsBuffer = [];

this.VERSION = VERSION;
this.VERSION = constant.VERSION;
this.config = {};

this.setupContext = function(contextWindow) {
Expand Down Expand Up @@ -126,61 +83,7 @@ var Karma = function(socket, context, navigator, location) {
this.info({log: values.join(', '), type: type});
};

this.stringify = function(obj, depth) {

if (depth === 0) {
return '...';
}

if (obj === null) {
return 'null';
}

switch (typeof obj) {
case 'string':
return '\'' + obj + '\'';
case 'undefined':
return 'undefined';
case 'function':
return obj.toString().replace(/\{[\s\S]*\}/, '{ ... }');
case 'boolean':
return obj ? 'true' : 'false';
case 'object':
var strs = [];
if (instanceOf(obj, 'Array')) {
strs.push('[');
for (var i = 0, ii = obj.length; i < ii; i++) {
if (i) {
strs.push(', ');
}
strs.push(this.stringify(obj[i], depth - 1));
}
strs.push(']');
} else if (instanceOf(obj, 'Date')) {
return obj.toString();
} else if (instanceOf(obj, 'Text')) {
return obj.nodeValue;
} else if (instanceOf(obj, 'Comment')) {
return '<!--' + obj.nodeValue + '-->';
} else if (obj.outerHTML) {
return obj.outerHTML;
} else {
strs.push(obj.constructor.name);
strs.push('{');
var first = true;
for(var key in obj) {
if (obj.hasOwnProperty(key)) {
if (first) { first = false; } else { strs.push(', '); }
strs.push(key + ': ' + this.stringify(obj[key], depth - 1));
}
}
strs.push('}');
}
return strs.join('');
default:
return obj;
}
};
this.stringify = stringify;


var clearContext = function() {
Expand Down Expand Up @@ -230,7 +133,7 @@ var Karma = function(socket, context, navigator, location) {

this.info = function(info) {
// TODO(vojta): introduce special API for this
if (!startEmitted && typeof info.total !== 'undefined') {
if (!startEmitted && util.isDefined(info.total)) {
socket.emit('start', info);
startEmitted = true;
} else {
Expand All @@ -250,11 +153,11 @@ var Karma = function(socket, context, navigator, location) {
};

this.store = function(key, value) {
if (typeof value === 'undefined') {
if (util.isUndefined(value)) {
return store[key];
}

if (Object.prototype.toString.apply(value) === '[object Array]') {
if (util.instanceOf(value, 'Array')) {
var s = store[key] = [];
for (var i = 0; i < value.length; i++) {
s.push(value[i]);
Expand All @@ -274,7 +177,7 @@ var Karma = function(socket, context, navigator, location) {
hasError = false;
startEmitted = false;
self.config = cfg;
context.src = CONTEXT_URL;
context.src = constant.CONTEXT_URL;

// clear the console before run
// works only on FF (Safari, Chrome do not allow to clear console from js source)
Expand All @@ -300,3 +203,5 @@ var Karma = function(socket, context, navigator, location) {
});
});
};

module.exports = Karma;
21 changes: 21 additions & 0 deletions client/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
var Karma = require('./karma');
var StatusUpdater = require('./updater');
var util = require('./util');

var KARMA_URL_ROOT = require('./constants').KARMA_URL_ROOT;


// connect socket.io
// https://github.com/LearnBoost/Socket.IO/wiki/Configuring-Socket.IO
var socket = io.connect('http://' + location.host, {
'reconnection delay': 500,
'reconnection limit': 2000,
'resource': KARMA_URL_ROOT.substr(1) + 'socket.io',
'sync disconnect on unload': true,
'max reconnection attempts': Infinity
});

// instantiate the updater of the view
new StatusUpdater(socket, util.elm('title'), util.elm('banner'), util.elm('browsers'));

window.karma = new Karma(socket, util.elm('context'), window.navigator, window.location);
60 changes: 60 additions & 0 deletions client/stringify.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
var instanceOf = require('./util').instanceOf;

var stringify = function stringify(obj, depth) {

if (depth === 0) {
return '...';
}

if (obj === null) {
return 'null';
}

switch (typeof obj) {
case 'string':
return '\'' + obj + '\'';
case 'undefined':
return 'undefined';
case 'function':
return obj.toString().replace(/\{[\s\S]*\}/, '{ ... }');
case 'boolean':
return obj ? 'true' : 'false';
case 'object':
var strs = [];
if (instanceOf(obj, 'Array')) {
strs.push('[');
for (var i = 0, ii = obj.length; i < ii; i++) {
if (i) {
strs.push(', ');
}
strs.push(stringify(obj[i], depth - 1));
}
strs.push(']');
} else if (instanceOf(obj, 'Date')) {
return obj.toString();
} else if (instanceOf(obj, 'Text')) {
return obj.nodeValue;
} else if (instanceOf(obj, 'Comment')) {
return '<!--' + obj.nodeValue + '-->';
} else if (obj.outerHTML) {
return obj.outerHTML;
} else {
strs.push(obj.constructor.name);
strs.push('{');
var first = true;
for(var key in obj) {
if (obj.hasOwnProperty(key)) {
if (first) { first = false; } else { strs.push(', '); }
strs.push(key + ': ' + stringify(obj[key], depth - 1));
}
}
strs.push('}');
}
return strs.join('');
default:
return obj;
}
};


module.exports = stringify;
33 changes: 33 additions & 0 deletions client/updater.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
var VERSION = require('./constants').VERSION;


var StatusUpdater = function(socket, titleElement, bannerElement, browsersElement) {
var updateBrowsersInfo = function(browsers) {
var items = [], status;
for (var i = 0; i < browsers.length; i++) {
status = browsers[i].isReady ? 'idle' : 'executing';
items.push('<li class="' + status + '">' + browsers[i].name + ' is ' + status + '</li>');
}
browsersElement.innerHTML = items.join('\n');
};

var updateBanner = function(status) {
return function(param) {
var paramStatus = param ? status.replace('$', param) : status;
titleElement.innerHTML = 'Karma v' + VERSION + ' - ' + paramStatus;
bannerElement.className = status === 'connected' ? 'online' : 'offline';
};
};

socket.on('connect', updateBanner('connected'));
socket.on('disconnect', updateBanner('disconnected'));
socket.on('reconnecting', updateBanner('reconnecting in $ ms...'));
socket.on('reconnect', updateBanner('connected'));
socket.on('reconnect_failed', updateBanner('failed to reconnect'));
socket.on('info', updateBrowsersInfo);
socket.on('disconnect', function() {
updateBrowsersInfo([]);
});
};

module.exports = StatusUpdater;
19 changes: 19 additions & 0 deletions client/util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
exports.instanceOf = function(value, constructorName) {
return Object.prototype.toString.apply(value) === '[object ' + constructorName + ']';
};

exports.elm = function(id) {
return document.getElementById(id);
};

exports.generateId = function(prefix) {
return prefix + Math.floor(Math.random() * 10000);
};

exports.isUndefined = function(value) {
return typeof value === 'undefined';
};

exports.isDefined = function(value) {
return !exports.isUndefined(value);
};
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@
"karma-qunit": "*",
"karma-coverage": "karma-runner/karma-coverage#karma-0.11",
"karma-requirejs": "*",
"karma-commonjs": "*",
"karma-growl-reporter": "*",
"karma-junit-reporter": "karma-runner/karma-junit-reporter#karma-0.11",
"karma-chrome-launcher": "*",
Expand All @@ -149,7 +150,8 @@
"karma-html2js-preprocessor": "*",
"karma-browserstack-launcher": "git://github.com/karma-runner/karma-browserstack-launcher.git",
"semver": "~1.1.4",
"grunt-contrib-watch": "~0.5.0"
"grunt-contrib-watch": "~0.5.0",
"grunt-browserify": "~1.2.4"
},
"main": "./lib/index",
"bin": {
Expand Down
8 changes: 0 additions & 8 deletions static/karma.wrapper

This file was deleted.

Loading

0 comments on commit 1bd50e0

Please sign in to comment.