|
@ -4,7 +4,6 @@ const assert = require('assert'); |
|
|
const zlib = require('zlib'); |
|
|
const zlib = require('zlib'); |
|
|
const path = require('path'); |
|
|
const path = require('path'); |
|
|
const fs = require('fs'); |
|
|
const fs = require('fs'); |
|
|
const util = require('util'); |
|
|
|
|
|
const stream = require('stream'); |
|
|
const stream = require('stream'); |
|
|
|
|
|
|
|
|
let zlibPairs = [ |
|
|
let zlibPairs = [ |
|
@ -48,60 +47,60 @@ if (process.env.FAST) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const tests = {}; |
|
|
const tests = {}; |
|
|
testFiles.forEach(function(file) { |
|
|
testFiles.forEach(common.mustCall((file) => { |
|
|
tests[file] = fs.readFileSync(path.resolve(common.fixturesDir, file)); |
|
|
tests[file] = fs.readFileSync(path.resolve(common.fixturesDir, file)); |
|
|
}); |
|
|
}, testFiles.length)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// stream that saves everything
|
|
|
// stream that saves everything
|
|
|
function BufferStream() { |
|
|
class BufferStream extends stream.Stream { |
|
|
|
|
|
constructor() { |
|
|
|
|
|
super(); |
|
|
this.chunks = []; |
|
|
this.chunks = []; |
|
|
this.length = 0; |
|
|
this.length = 0; |
|
|
this.writable = true; |
|
|
this.writable = true; |
|
|
this.readable = true; |
|
|
this.readable = true; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
util.inherits(BufferStream, stream.Stream); |
|
|
write(c) { |
|
|
|
|
|
|
|
|
BufferStream.prototype.write = function(c) { |
|
|
|
|
|
this.chunks.push(c); |
|
|
this.chunks.push(c); |
|
|
this.length += c.length; |
|
|
this.length += c.length; |
|
|
return true; |
|
|
return true; |
|
|
}; |
|
|
} |
|
|
|
|
|
|
|
|
BufferStream.prototype.end = function(c) { |
|
|
end(c) { |
|
|
if (c) this.write(c); |
|
|
if (c) this.write(c); |
|
|
// flatten
|
|
|
// flatten
|
|
|
const buf = Buffer.allocUnsafe(this.length); |
|
|
const buf = Buffer.allocUnsafe(this.length); |
|
|
let i = 0; |
|
|
let i = 0; |
|
|
this.chunks.forEach(function(c) { |
|
|
this.chunks.forEach((c) => { |
|
|
c.copy(buf, i); |
|
|
c.copy(buf, i); |
|
|
i += c.length; |
|
|
i += c.length; |
|
|
}); |
|
|
}); |
|
|
this.emit('data', buf); |
|
|
this.emit('data', buf); |
|
|
this.emit('end'); |
|
|
this.emit('end'); |
|
|
return true; |
|
|
return true; |
|
|
}; |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
function SlowStream(trickle) { |
|
|
class SlowStream extends stream.Stream { |
|
|
|
|
|
constructor(trickle) { |
|
|
|
|
|
super(); |
|
|
this.trickle = trickle; |
|
|
this.trickle = trickle; |
|
|
this.offset = 0; |
|
|
this.offset = 0; |
|
|
this.readable = this.writable = true; |
|
|
this.readable = this.writable = true; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
util.inherits(SlowStream, stream.Stream); |
|
|
write() { |
|
|
|
|
|
|
|
|
SlowStream.prototype.write = function() { |
|
|
|
|
|
throw new Error('not implemented, just call ss.end(chunk)'); |
|
|
throw new Error('not implemented, just call ss.end(chunk)'); |
|
|
}; |
|
|
} |
|
|
|
|
|
|
|
|
SlowStream.prototype.pause = function() { |
|
|
pause() { |
|
|
this.paused = true; |
|
|
this.paused = true; |
|
|
this.emit('pause'); |
|
|
this.emit('pause'); |
|
|
}; |
|
|
} |
|
|
|
|
|
|
|
|
SlowStream.prototype.resume = function() { |
|
|
resume() { |
|
|
const emit = () => { |
|
|
const emit = () => { |
|
|
if (this.paused) return; |
|
|
if (this.paused) return; |
|
|
if (this.offset >= this.length) { |
|
|
if (this.offset >= this.length) { |
|
@ -120,33 +119,32 @@ SlowStream.prototype.resume = function() { |
|
|
if (!this.chunk) return; |
|
|
if (!this.chunk) return; |
|
|
this.paused = false; |
|
|
this.paused = false; |
|
|
emit(); |
|
|
emit(); |
|
|
}; |
|
|
} |
|
|
|
|
|
|
|
|
SlowStream.prototype.end = function(chunk) { |
|
|
end(chunk) { |
|
|
// walk over the chunk in blocks.
|
|
|
// walk over the chunk in blocks.
|
|
|
this.chunk = chunk; |
|
|
this.chunk = chunk; |
|
|
this.length = chunk.length; |
|
|
this.length = chunk.length; |
|
|
this.resume(); |
|
|
this.resume(); |
|
|
return this.ended; |
|
|
return this.ended; |
|
|
}; |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// for each of the files, make sure that compressing and
|
|
|
// for each of the files, make sure that compressing and
|
|
|
// decompressing results in the same data, for every combination
|
|
|
// decompressing results in the same data, for every combination
|
|
|
// of the options set above.
|
|
|
// of the options set above.
|
|
|
let failures = 0; |
|
|
|
|
|
let total = 0; |
|
|
|
|
|
let done = 0; |
|
|
|
|
|
|
|
|
|
|
|
Object.keys(tests).forEach(function(file) { |
|
|
const testKeys = Object.keys(tests); |
|
|
|
|
|
testKeys.forEach(common.mustCall((file) => { |
|
|
const test = tests[file]; |
|
|
const test = tests[file]; |
|
|
chunkSize.forEach(function(chunkSize) { |
|
|
chunkSize.forEach(common.mustCall((chunkSize) => { |
|
|
trickle.forEach(function(trickle) { |
|
|
trickle.forEach(common.mustCall((trickle) => { |
|
|
windowBits.forEach(function(windowBits) { |
|
|
windowBits.forEach(common.mustCall((windowBits) => { |
|
|
level.forEach(function(level) { |
|
|
level.forEach(common.mustCall((level) => { |
|
|
memLevel.forEach(function(memLevel) { |
|
|
memLevel.forEach(common.mustCall((memLevel) => { |
|
|
strategy.forEach(function(strategy) { |
|
|
strategy.forEach(common.mustCall((strategy) => { |
|
|
zlibPairs.forEach(function(pair) { |
|
|
zlibPairs.forEach(common.mustCall((pair) => { |
|
|
const Def = pair[0]; |
|
|
const Def = pair[0]; |
|
|
const Inf = pair[1]; |
|
|
const Inf = pair[1]; |
|
|
const opts = { level: level, |
|
|
const opts = { level: level, |
|
@ -154,57 +152,32 @@ Object.keys(tests).forEach(function(file) { |
|
|
memLevel: memLevel, |
|
|
memLevel: memLevel, |
|
|
strategy: strategy }; |
|
|
strategy: strategy }; |
|
|
|
|
|
|
|
|
total++; |
|
|
|
|
|
|
|
|
|
|
|
const def = new Def(opts); |
|
|
const def = new Def(opts); |
|
|
const inf = new Inf(opts); |
|
|
const inf = new Inf(opts); |
|
|
const ss = new SlowStream(trickle); |
|
|
const ss = new SlowStream(trickle); |
|
|
const buf = new BufferStream(); |
|
|
const buf = new BufferStream(); |
|
|
|
|
|
|
|
|
// verify that the same exact buffer comes out the other end.
|
|
|
// verify that the same exact buffer comes out the other end.
|
|
|
buf.on('data', function(c) { |
|
|
buf.on('data', common.mustCall((c) => { |
|
|
const msg = `${file} ${chunkSize} ${ |
|
|
const msg = `${file} ${chunkSize} ${ |
|
|
JSON.stringify(opts)} ${Def.name} -> ${Inf.name}`;
|
|
|
JSON.stringify(opts)} ${Def.name} -> ${Inf.name}`;
|
|
|
let ok = true; |
|
|
|
|
|
const testNum = ++done; |
|
|
|
|
|
let i; |
|
|
let i; |
|
|
for (i = 0; i < Math.max(c.length, test.length); i++) { |
|
|
for (i = 0; i < Math.max(c.length, test.length); i++) { |
|
|
if (c[i] !== test[i]) { |
|
|
if (c[i] !== test[i]) { |
|
|
ok = false; |
|
|
assert.fail(null, null, msg); |
|
|
failures++; |
|
|
|
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
if (ok) { |
|
|
})); |
|
|
console.log(`ok ${testNum} ${msg}`); |
|
|
|
|
|
} else { |
|
|
|
|
|
console.log(`not ok ${testNum} msg`); |
|
|
|
|
|
console.log(' ...'); |
|
|
|
|
|
console.log(` testfile: ${file}`); |
|
|
|
|
|
console.log(` type: ${Def.name} -> ${Inf.name}`); |
|
|
|
|
|
console.log(` position: ${i}`); |
|
|
|
|
|
console.log(` options: ${JSON.stringify(opts)}`); |
|
|
|
|
|
console.log(` expect: ${test[i]}`); |
|
|
|
|
|
console.log(` actual: ${c[i]}`); |
|
|
|
|
|
console.log(` chunkSize: ${chunkSize}`); |
|
|
|
|
|
console.log(' ---'); |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// the magic happens here.
|
|
|
// the magic happens here.
|
|
|
ss.pipe(def).pipe(inf).pipe(buf); |
|
|
ss.pipe(def).pipe(inf).pipe(buf); |
|
|
ss.end(test); |
|
|
ss.end(test); |
|
|
}); |
|
|
}, zlibPairs.length)); |
|
|
}); |
|
|
}, strategy.length)); |
|
|
}); |
|
|
}, memLevel.length)); |
|
|
}); |
|
|
}, level.length)); |
|
|
}); |
|
|
}, windowBits.length)); |
|
|
}); |
|
|
}, trickle.length)); |
|
|
}); |
|
|
}, chunkSize.length)); |
|
|
}); |
|
|
}, testKeys.length)); |
|
|
|
|
|
|
|
|
process.on('exit', function(code) { |
|
|
|
|
|
console.log(`1..${done}`); |
|
|
|
|
|
assert.strictEqual(done, total, `${total - done} tests left unfinished`); |
|
|
|
|
|
assert.strictEqual(failures, 0, 'some test failures'); |
|
|
|
|
|
}); |
|
|
|
|
|