Standalone server initial implementation
- no dependency over Windshaft.Server
This commit is contained in:
+124
-100
@@ -9,64 +9,6 @@ var exec = require('child_process').exec,
|
||||
|
||||
var assert = module.exports = exports = require('assert');
|
||||
|
||||
// @param tolerance number of tolerated grid cell differences
|
||||
assert.utfgridEqualsFile = function(buffer, file_b, tolerance, callback) {
|
||||
fs.writeFileSync('/tmp/grid.json', buffer, 'binary'); // <-- to debug/update
|
||||
var expected_json = JSON.parse(fs.readFileSync(file_b, 'utf8'));
|
||||
|
||||
var err = null;
|
||||
|
||||
var Celldiff = function(x, y, ev, ov) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.ev = ev;
|
||||
this.ov = ov;
|
||||
};
|
||||
|
||||
Celldiff.prototype.toString = function() {
|
||||
return '(' + this.x + ',' + this.y + ')["' + this.ev + '" != "' + this.ov + '"]';
|
||||
};
|
||||
|
||||
try {
|
||||
var obtained_json = JSON.parse(buffer);
|
||||
|
||||
// compare grid
|
||||
var obtained_grid = obtained_json.grid;
|
||||
var expected_grid = expected_json.grid;
|
||||
var nrows = obtained_grid.length
|
||||
if (nrows != expected_grid.length) {
|
||||
throw new Error( "Obtained grid rows (" + nrows +
|
||||
") != expected grid rows (" + expected_grid.length + ")" );
|
||||
}
|
||||
var celldiff = [];
|
||||
for (var i=0; i<nrows; ++i) {
|
||||
var ocols = obtained_grid[i];
|
||||
var ecols = expected_grid[i];
|
||||
var ncols = ocols.length;
|
||||
if ( ncols != ecols.length ) {
|
||||
throw new Error( "Obtained grid cols (" + ncols +
|
||||
") != expected grid cols (" + ecols.length +
|
||||
") on row " + i );
|
||||
}
|
||||
for (var j=0; j<ncols; ++j) {
|
||||
var ocell = ocols[j];
|
||||
var ecell = ecols[j];
|
||||
if ( ocell !== ecell ) {
|
||||
celldiff.push(new Celldiff(i, j, ecell, ocell));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( celldiff.length > tolerance ) {
|
||||
throw new Error( celldiff.length + " cell differences: " + celldiff );
|
||||
}
|
||||
|
||||
assert.deepEqual(obtained_json.keys, expected_json.keys);
|
||||
} catch (e) { err = e; }
|
||||
|
||||
callback(err);
|
||||
};
|
||||
|
||||
/**
|
||||
* Takes an image data as an input and an image path and compare them using ImageMagick fuzz algorithm, if case the
|
||||
* similarity is not within the tolerance limit it will callback with an error.
|
||||
@@ -78,15 +20,38 @@ assert.utfgridEqualsFile = function(buffer, file_b, tolerance, callback) {
|
||||
* @see FUZZY in http://www.imagemagick.org/script/command-line-options.php#metric
|
||||
*/
|
||||
assert.imageEqualsFile = function(buffer, referenceImageRelativeFilePath, tolerance, callback) {
|
||||
if (!callback) callback = function(err) { if (err) throw err; };
|
||||
callback = callback || function(err) { assert.ifError(err); };
|
||||
var referenceImageFilePath = path.resolve(referenceImageRelativeFilePath),
|
||||
testImageFilePath = '/tmp/windshaft-test-image-' + (Math.random() * 1e16); // TODO: make predictable
|
||||
var err = fs.writeFileSync(testImageFilePath, buffer, 'binary');
|
||||
if (err) throw err;
|
||||
testImageFilePath = createImageFromBuffer(buffer, 'test');
|
||||
|
||||
imageFilesAreEqual(testImageFilePath, referenceImageFilePath, tolerance, function(err) {
|
||||
fs.unlinkSync(testImageFilePath);
|
||||
callback(err);
|
||||
});
|
||||
};
|
||||
|
||||
assert.imageBuffersAreEqual = function(bufferA, bufferB, tolerance, callback) {
|
||||
var randStr = (Math.random() * 1e16).toString().substring(0, 8);
|
||||
var imageFilePathA = createImageFromBuffer(bufferA, randStr + '-a'),
|
||||
imageFilePathB = createImageFromBuffer(bufferB, randStr + '-b');
|
||||
|
||||
imageFilesAreEqual(imageFilePathA, imageFilePathB, tolerance, function(err, similarity) {
|
||||
callback(err, [imageFilePathA, imageFilePathB], similarity);
|
||||
});
|
||||
};
|
||||
|
||||
function createImageFromBuffer(buffer, nameHint) {
|
||||
var imageFilePath = path.resolve('test/results/png/image-' + nameHint + '-' + Date.now() + '.png');
|
||||
var err = fs.writeFileSync(imageFilePath, buffer, 'binary');
|
||||
assert.ifError(err);
|
||||
return imageFilePath;
|
||||
}
|
||||
|
||||
function imageFilesAreEqual(testImageFilePath, referenceImageFilePath, tolerance, callback) {
|
||||
var resultFilePath = path.resolve(util.format('/tmp/windshaft-result-%s-diff.png', Date.now()));
|
||||
var imageMagickCmd = util.format(
|
||||
'compare -metric fuzz "%s" "%s" /dev/null',
|
||||
testImageFilePath, referenceImageFilePath
|
||||
'compare -metric fuzz "%s" "%s" "%s"',
|
||||
testImageFilePath, referenceImageFilePath, resultFilePath
|
||||
);
|
||||
|
||||
exec(imageMagickCmd, function(err, stdout, stderr) {
|
||||
@@ -104,29 +69,29 @@ assert.imageEqualsFile = function(buffer, referenceImageRelativeFilePath, tolera
|
||||
tolerancePerMil = (tolerance / 1000);
|
||||
if (similarity > tolerancePerMil) {
|
||||
err = new Error(util.format(
|
||||
'Images %s and %s are not equal (got %d similarity, expected %d)',
|
||||
testImageFilePath, referenceImageFilePath, similarity, tolerancePerMil)
|
||||
'Images %s and %s are not equal (got %d similarity, expected %d). Result %s',
|
||||
testImageFilePath, referenceImageFilePath, similarity, tolerancePerMil, resultFilePath)
|
||||
);
|
||||
err.similarity = similarity;
|
||||
callback(err);
|
||||
callback(err, similarity);
|
||||
} else {
|
||||
fs.unlinkSync(testImageFilePath);
|
||||
callback(null);
|
||||
fs.unlinkSync(resultFilePath);
|
||||
callback(null, similarity);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert response from `server` with
|
||||
* the given `req` object and `res` assertions object.
|
||||
*
|
||||
* @param {Server} server
|
||||
* @param {Server|Object} server
|
||||
* @param {Object} req
|
||||
* @param {Object|Function} res
|
||||
* @param {String} msg
|
||||
* @param {String|Function} msg
|
||||
*/
|
||||
// jshint maxcomplexity:12
|
||||
assert.response = function(server, req, res, msg){
|
||||
var port = 5555;
|
||||
function check(){
|
||||
@@ -161,14 +126,12 @@ assert.response = function(server, req, res, msg){
|
||||
}
|
||||
|
||||
// Callback as third or fourth arg
|
||||
var callback = typeof res === 'function'
|
||||
? res
|
||||
: typeof msg === 'function'
|
||||
? msg
|
||||
: function(){};
|
||||
var callback = typeof res === 'function' ? res : (typeof msg === 'function' ? msg : function(){});
|
||||
|
||||
// Default messate to test title
|
||||
if (typeof msg === 'function') msg = null;
|
||||
if (typeof msg === 'function') {
|
||||
msg = null;
|
||||
}
|
||||
msg = msg || assert.testTitle;
|
||||
msg += '. ';
|
||||
|
||||
@@ -183,6 +146,7 @@ assert.response = function(server, req, res, msg){
|
||||
issue();
|
||||
}
|
||||
|
||||
// jshint maxcomplexity:8
|
||||
function issue(){
|
||||
|
||||
// Issue request
|
||||
@@ -217,27 +181,29 @@ assert.response = function(server, req, res, msg){
|
||||
}, requestTimeout);
|
||||
}
|
||||
|
||||
if (data) request.write(data);
|
||||
if (data) {
|
||||
request.write(data);
|
||||
}
|
||||
|
||||
request.on('response', function(response){
|
||||
response.body = '';
|
||||
response.setEncoding(encoding);
|
||||
response.on('data', function(chunk){ response.body += chunk; });
|
||||
response.on('end', function(){
|
||||
if (timer) clearTimeout(timer);
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
|
||||
check();
|
||||
|
||||
// Assert response body
|
||||
if (res.body !== undefined) {
|
||||
var eql = res.body instanceof RegExp
|
||||
? res.body.test(response.body)
|
||||
: res.body === response.body;
|
||||
var eql = res.body instanceof RegExp ? res.body.test(response.body) : res.body === response.body;
|
||||
assert.ok(
|
||||
eql,
|
||||
msg + 'Invalid response body.\n'
|
||||
+ ' Expected: ' + res.body + '\n'
|
||||
+ ' Got: ' + response.body
|
||||
msg + colorize('[red]{Invalid response body.}\n' +
|
||||
' Expected: [green]{' + res.body + '}\n' +
|
||||
' Got: [red]{' + response.body + '}')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -246,10 +212,10 @@ assert.response = function(server, req, res, msg){
|
||||
assert.equal(
|
||||
response.statusCode,
|
||||
status,
|
||||
msg + colorize('Invalid response status code.\n'
|
||||
+ ' Expected: [green]{' + status + '}\n'
|
||||
+ ' Got: [red]{' + response.statusCode + '}\n'
|
||||
+ ' Response body: ' + response.body)
|
||||
msg + colorize('[red]{Invalid response status code.}\n' +
|
||||
' Expected: [green]{' + status + '}\n' +
|
||||
' Got: [red]{' + response.statusCode + '}\n' +
|
||||
' Body: ' + response.body)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -260,14 +226,12 @@ assert.response = function(server, req, res, msg){
|
||||
var name = keys[i],
|
||||
actual = response.headers[name.toLowerCase()],
|
||||
expected = res.headers[name],
|
||||
eql = expected instanceof RegExp
|
||||
? expected.test(actual)
|
||||
: expected == actual;
|
||||
headerEql = expected instanceof RegExp ? expected.test(actual) : expected === actual;
|
||||
assert.ok(
|
||||
eql,
|
||||
msg + 'Invalid response header [bold]{' + name + '}.\n'
|
||||
+ ' Expected: [green]{' + expected + '}\n'
|
||||
+ ' Got: [red]{' + actual + '}'
|
||||
headerEql,
|
||||
msg + colorize('Invalid response header [bold]{' + name + '}.\n' +
|
||||
' Expected: [green]{' + expected + '}\n' +
|
||||
' Got: [red]{' + actual + '}')
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -278,9 +242,69 @@ assert.response = function(server, req, res, msg){
|
||||
});
|
||||
|
||||
request.end();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// @param tolerance number of tolerated grid cell differences
|
||||
// jshint maxcomplexity:8
|
||||
assert.utfgridEqualsFile = function(buffer, file_b, tolerance, callback) {
|
||||
fs.writeFileSync('/tmp/grid.json', buffer, 'binary'); // <-- to debug/update
|
||||
var expected_json = JSON.parse(fs.readFileSync(file_b, 'utf8'));
|
||||
|
||||
var err = null;
|
||||
|
||||
var Celldiff = function(x, y, ev, ov) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.ev = ev;
|
||||
this.ov = ov;
|
||||
};
|
||||
|
||||
Celldiff.prototype.toString = function() {
|
||||
return '(' + this.x + ',' + this.y + ')["' + this.ev + '" != "' + this.ov + '"]';
|
||||
};
|
||||
|
||||
try {
|
||||
var obtained_json = JSON.parse(buffer);
|
||||
|
||||
// compare grid
|
||||
var obtained_grid = obtained_json.grid;
|
||||
var expected_grid = expected_json.grid;
|
||||
var nrows = obtained_grid.length;
|
||||
if (nrows !== expected_grid.length) {
|
||||
throw new Error( "Obtained grid rows (" + nrows +
|
||||
") != expected grid rows (" + expected_grid.length + ")" );
|
||||
}
|
||||
var celldiff = [];
|
||||
for (var i=0; i<nrows; ++i) {
|
||||
var ocols = obtained_grid[i];
|
||||
var ecols = expected_grid[i];
|
||||
var ncols = ocols.length;
|
||||
if ( ncols !== ecols.length ) {
|
||||
throw new Error( "Obtained grid cols (" + ncols +
|
||||
") != expected grid cols (" + ecols.length +
|
||||
") on row " + i );
|
||||
}
|
||||
for (var j=0; j<ncols; ++j) {
|
||||
var ocell = ocols[j];
|
||||
var ecell = ecols[j];
|
||||
if ( ocell !== ecell ) {
|
||||
celldiff.push(new Celldiff(i, j, ecell, ocell));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( celldiff.length > tolerance ) {
|
||||
throw new Error( celldiff.length + " cell differences: " + celldiff );
|
||||
}
|
||||
|
||||
assert.deepEqual(obtained_json.keys, expected_json.keys);
|
||||
} catch (e) { err = e; }
|
||||
|
||||
callback(err);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Colorize the given string using ansi-escape sequences.
|
||||
* Disabled when --boring is set.
|
||||
@@ -293,4 +317,4 @@ function colorize(str) {
|
||||
return str.replace(/\[(\w+)\]\{([^]*?)\}/g, function(_, color, str) {
|
||||
return '\x1B[' + colors[color] + 'm' + str + '\x1B[0m';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user