I am using mocha/supertest/should.js to test my Rest Service
GET /files/
returns file as stream.
How can I assert in should.js
Solution using file-compare
and node-temp
:
it('should return test2.json as a stream', function (done) {
var writeStream = temp.createWriteStream();
temp.track();
var req = api.get('/files/7386afde8992');
req.on('end', function() {
comparator.compare(writeStream.path, TEST2_JSON_FILE, function(result, err) {
if (err) {
return done(err);
}
result.should.true;
done();
});
});
req.pipe(writeStream);
});
You have 3 solutions:
First:
Compare the result strings
tmpBuf.toString() === testBuf.toString();
Second:
Using a loop to read the buffers byte by byte
var index = 0,
length = tmpBuf.length,
match = true;
while (index < length) {
if (tmpBuf[index] === testBuf[index]) {
index++;
} else {
match = false;
break;
}
}
match; // true -> contents are the same, false -> otherwise
Third:
Using a third-party module like buffertools and buffertools.compare(buffer, buffer|string) method.
Surprisingly, no one has suggested Buffer.equals. That seems to be the fastest and simplest approach and has been around since v0.11.
So your code would become tmpBuf.equals(testBuf)
In should.js
you can use .eql
to compare Buffer's instances:
> var buf1 = new Buffer('abc');
undefined
> var buf2 = new Buffer('abc');
undefined
> var buf3 = new Buffer('dsfg');
undefined
> buf1.should.be.eql(buf1)
...
> buf1.should.be.eql(buf2)
...
> buf1.should.be.eql(buf3)
AssertionError: expected <Buffer 61 62 63> to equal <Buffer 64 73 66 67>
...
>
I think that you should use non-blocking calls in JavaScript to get a better performance, at least to prevent from blocking other operations:
Blocking is when the execution of additional JavaScript in the Node.js process must wait until a non-JavaScript operation completes. This happens because the event loop is unable to continue running JavaScript while a blocking operation is occurring.
In Node.js, JavaScript that exhibits poor performance due to being CPU intensive rather than waiting on a non-JavaScript operation, such as I/O, isn't typically referred to as blocking. Synchronous methods in the Node.js standard library that use libuv are the most commonly used blocking operations. Native modules may also have blocking methods.
So, I would change the Sync
calls with something like the following code. Also, I would use the method equals
that Max
suggest to compare both files:
const fs = require('fs')
fs.readFile('file1', (err, data1) => {
if (err) throw err;
fs.readFile('file2', (err, data2) => {
if (err) throw err;
if (data1.equals(data2)) {
console.log('EQUAL')
} else {
console.log('NON EQUAL')
}
});
});
Though for a small and a single script the result would be almost the same
for comparing large files e.g. images when asserting file uploads a comparison of buffers or strings with should.eql
takes ages. i recommend asserting the buffer hash with the crypto module:
const buf1Hash = crypto.createHash('sha256').update(buf1).digest();
const buf2Hash = crypto.createHash('sha256').update(buf2).digest();
buf1Hash.should.eql(buf2Hash);
an easier approach is asserting the buffer length like so:
buf1.length.should.eql(buf2.length)
instead of using shouldjs as assertion module you can surely use a different tool