diff --git a/index.js b/index.js index e77532a..1a75e90 100644 --- a/index.js +++ b/index.js @@ -11,60 +11,60 @@ var PLUGIN_NAME = 'gulp-gzip'; module.exports = function (options) { - // Combine user defined options with default options - var config = utils.merge({ append: true, threshold: false, gzipOptions: {} }, options); + // Combine user defined options with default options + var config = utils.merge({ append: true, threshold: false, gzipOptions: {} }, options); - // Create a through2 object stream. This is our plugin export - var stream = through2.obj(compress); + // Create a through2 object stream. This is our plugin export + var stream = through2.obj(compress); - // Expose the config so we can test it - stream.config = config; + // Expose the config so we can test it + stream.config = config; - function compress(file, enc, done) { + function compress(file, enc, done) { - /*jshint validthis: true */ - var self = this; + /*jshint validthis: true */ + var self = this; - // Check for empty file - if (file.isNull()) { - // Pass along the empty file to the next plugin - self.push(file); - done(); - return; - } + // Check for empty file + if (file.isNull()) { + // Pass along the empty file to the next plugin + self.push(file); + done(); + return; + } - // Call when finished with compression - var finished = function(err, contents, wasCompressed) { - if (err) { - var error = new PluginError(PLUGIN_NAME, err, { showStack: true }); - self.emit('error', error); - done(); - return; - } + // Call when finished with compression + var finished = function(err, contents, wasCompressed) { + if (err) { + var error = new PluginError(PLUGIN_NAME, err, { showStack: true }); + self.emit('error', error); + done(); + return; + } - if (wasCompressed) { - if (file.contentEncoding) { - file.contentEncoding.push('gzip'); - } else { - file.contentEncoding = [ 'gzip' ]; - } - if (config.append) { - file.path += '.gz'; - } - } - file.contents = contents; - self.push(file); - done(); - return; - }; + if (wasCompressed) { + if (file.contentEncoding) { + file.contentEncoding.push('gzip'); + } else { + file.contentEncoding = [ 'gzip' ]; + } + if (config.append) { + file.path += '.gz'; + } + } + file.contents = contents; + self.push(file); + done(); + return; + }; - // Check if file contents is a buffer or a stream - if (file.isBuffer()) { - bufferMode(file.contents, config, finished); - } else { - streamMode(file.contents, config, finished); - } - } + // Check if file contents is a buffer or a stream + if (file.isBuffer()) { + bufferMode(file.contents, config, finished); + } else { + streamMode(file.contents, config, finished); + } + } - return stream; + return stream; }; diff --git a/lib/bufferMode.js b/lib/bufferMode.js index 887cdec..8dd4bc8 100644 --- a/lib/bufferMode.js +++ b/lib/bufferMode.js @@ -3,34 +3,34 @@ var Readable = require('stream').Readable; var toArray = require('stream-to-array'); module.exports = function(contents, options, callback) { - // Check if the threshold option is set - // If true, check if the buffer length is greater than the threshold - if (options.threshold && contents.length < options.threshold) { - // File size is smaller than the threshold - // Pass it along to the next plugin without compressing - callback(null, contents, false); - return; - } + // Check if the threshold option is set + // If true, check if the buffer length is greater than the threshold + if (options.threshold && contents.length < options.threshold) { + // File size is smaller than the threshold + // Pass it along to the next plugin without compressing + callback(null, contents, false); + return; + } - // Create a readable stream out of the contents - var rs = new Readable({ objectMode: true }); - rs._read = function() { - rs.push(contents); - rs.push(null); - }; + // Create a readable stream out of the contents + var rs = new Readable({ objectMode: true }); + rs._read = function() { + rs.push(contents); + rs.push(null); + }; - // Compress the contents - var gzipStream = zlib.createGzip(options.gzipOptions); - rs.pipe(gzipStream); + // Compress the contents + var gzipStream = zlib.createGzip(options.gzipOptions); + rs.pipe(gzipStream); - // Turn gzip stream back into a buffer - toArray(gzipStream, function (err, chunks) { - if (err) { - callback(err, null, false); - return; - } + // Turn gzip stream back into a buffer + toArray(gzipStream, function (err, chunks) { + if (err) { + callback(err, null, false); + return; + } - callback(null, Buffer.concat(chunks), true); - return; - }); -}; \ No newline at end of file + callback(null, Buffer.concat(chunks), true); + return; + }); +}; diff --git a/lib/streamMode.js b/lib/streamMode.js index 2e0c590..91db2a1 100644 --- a/lib/streamMode.js +++ b/lib/streamMode.js @@ -3,35 +3,35 @@ var through2 = require('through2'); var toArray = require('stream-to-array'); module.exports = function(contents, options, callback) { - // Check if the threshold option is set - if (options.threshold) { - // Check if the stream contents is less than the threshold - toArray(contents, function (err, chunks) { - if (err) { - callback(err, null, false); - return; - } + // Check if the threshold option is set + if (options.threshold) { + // Check if the stream contents is less than the threshold + toArray(contents, function (err, chunks) { + if (err) { + callback(err, null, false); + return; + } - // Join chunks array into a single buffer - var buffer = Buffer.concat(chunks); + // Join chunks array into a single buffer + var buffer = Buffer.concat(chunks); - // Create a stream to return to the callback - var contentStream = through2(); - contentStream.end(buffer); + // Create a stream to return to the callback + var contentStream = through2(); + contentStream.end(buffer); - // Check if the stream content length is less than the threshold - if (buffer.length < options.threshold) { - // File does not meet the minimum size requirement for compression - callback(null, contentStream, false); - } else { - // File meets the minimum size requirement for compression - var gzipStream = zlib.createGzip(options.gzipOptions); - callback(null, contentStream.pipe(gzipStream), true); - } - }); - } else { - // Compress the file contents - var gzipStream = zlib.createGzip(options.gzipOptions); - callback(null, contents.pipe(gzipStream), true); - } -}; \ No newline at end of file + // Check if the stream content length is less than the threshold + if (buffer.length < options.threshold) { + // File does not meet the minimum size requirement for compression + callback(null, contentStream, false); + } else { + // File meets the minimum size requirement for compression + var gzipStream = zlib.createGzip(options.gzipOptions); + callback(null, contentStream.pipe(gzipStream), true); + } + }); + } else { + // Compress the file contents + var gzipStream = zlib.createGzip(options.gzipOptions); + callback(null, contents.pipe(gzipStream), true); + } +}; diff --git a/lib/utils.js b/lib/utils.js index 592c262..5658e1c 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -3,41 +3,41 @@ var bytes = require('bytes'); // Merge source object with target object while handling threshold option // Used to merge user defined plugin options with default options function merge(target, source) { - if (typeof source === 'undefined') source = {}; + if (typeof source === 'undefined') source = {}; - Object.keys(source).forEach(function(key) { - if (key === 'threshold') { - target[key] = threshold(source[key]); - } else { - target[key] = source[key]; - } - }); + Object.keys(source).forEach(function(key) { + if (key === 'threshold') { + target[key] = threshold(source[key]); + } else { + target[key] = source[key]; + } + }); - return target; + return target; } // Parse the threshold plugin option // Specifies the minimum file size that will be compressed // Can be a string, number, or boolean function threshold(obj) { - var ret; + var ret; - switch (typeof obj) { - case 'string': - ret = bytes(obj) < 150 ? 150 : bytes(obj); - break; - case 'number': - ret = obj < 150 ? 150 : obj; - break; - case 'boolean': - ret = obj === false ? false : 150; - break; - default: - throw new Error('threshold must be String|Number|Boolean'); - } + switch (typeof obj) { + case 'string': + ret = bytes(obj) < 150 ? 150 : bytes(obj); + break; + case 'number': + ret = obj < 150 ? 150 : obj; + break; + case 'boolean': + ret = obj === false ? false : 150; + break; + default: + throw new Error('threshold must be String|Number|Boolean'); + } - return ret; + return ret; } exports.merge = merge; -exports.threshold = threshold; \ No newline at end of file +exports.threshold = threshold; diff --git a/test/test.js b/test/test.js index 6ac27bc..0ad7678 100644 --- a/test/test.js +++ b/test/test.js @@ -16,451 +16,451 @@ process.chdir('./test'); describe('gulp-gzip', function() { - describe('plugin level', function() { - - describe('config', function() { - - it('should have default config', function(done) { - var instance = gzip(); - instance.config.should.eql({ append: true, gzipOptions: {}, threshold: false }); - done(); - }); - - it('should merge options with defaults', function(done) { - var instance = gzip({ append: false }); - instance.config.should.eql({ append: false, gzipOptions: {}, threshold: false }); - done(); - }); - - it('should set threshold to false while receiving false', function(done) { - var instance = gzip({ threshold: false }); - instance.config.threshold.should.be.false; - done(); - }); - - it('should set threshold to 150 while receiving true', function(done) { - var instance = gzip({ threshold: true }); - instance.config.threshold.should.eql(150); - done(); - }); - - it('should set threshold to Number while receiving Number', function(done) { - var instance = gzip({ threshold: 1024 }); - instance.config.should.have.property('threshold', 1024); - done(); - }); - - it('should set threshold to 150 while receiving Number < 150', function(done) { - var instance = gzip({ threshold: 100 }); - instance.config.should.have.property('threshold', 150); - done(); - }); - - it('should set threshold to Number while receiving String (bytes result)', function(done) { - var instance = gzip({ threshold: '1kb' }); - instance.config.should.have.property('threshold', 1024); - done(); - }); - - it('should set threshold to 150 while receiving String (bytes result < 150)', function(done) { - var instance = gzip({ threshold: '1kb' }); - instance.config.should.have.property('threshold', 1024); - done(); - }); - - it('should set gzipOptions', function(done) { - var instance = gzip({ gzipOptions: { level: 9, memLevel: 1} }); - instance.config.should.have.property('gzipOptions'); - instance.config.gzipOptions.should.have.property('level', 9); - instance.config.gzipOptions.should.have.property('memLevel', 1); - done(); - }); - }); - }); - - describe('handler level', function() { - - describe('file extension', function() { - - it('should append .gz to the file extension, by default', function(done) { - gulp.src('files/small.txt') - .pipe(gzip()) - .pipe(tap(function(file) { - file.path.should.endWith('.gz'); - done(); - })); - }); - - it('should not append .gz to the file extension receiving { append: false }', function(done) { - gulp.src('files/small.txt') - .pipe(gzip({ append: false })) - .pipe(tap(function(file) { - file.path.should.not.endWith('.gz'); - done(); - })); - }); - }); - - describe('buffer mode', function() { - - it('should create file with .gz extension, by default', function(done) { - var id = nid(); - var out = gulp.dest('tmp'); - - out.on('end', function() { - fs.readFile('./tmp/' + id + '.txt.gz', function(err, file) { - should.not.exist(err); - should.exist(file); - file.should.not.be.empty; - done(); - }); - }); - - gulp.src('files/small.txt') - .pipe(rename({ basename: id })) - .pipe(gzip()) - .pipe(out); - }); - - it('should create file without .gz extension when { append: false }', function(done) { - var id = nid(); - var out = gulp.dest('tmp'); - - out.on('end', function() { - fs.readFile('./tmp/' + id + '.txt', function(err, file) { - should.not.exist(err); - should.exist(file); - file.should.not.be.empty; - done(); - }); - }); - - gulp.src('files/small.txt') - .pipe(rename({ basename: id })) - .pipe(gzip({ append: false })) - .pipe(out); - }); - - it('should return file contents as a Buffer', function(done) { - gulp.src('files/small.txt') - .pipe(gzip()) - .pipe(tap(function(file) { - file.contents.should.be.instanceof(Buffer); - done(); - })); - }); - - it('should return file contents as a Buffer while handling threshold', function(done) { - gulp.src('files/big.txt') - .pipe(gzip({ threshold: '1kb' })) - .pipe(tap(function(file) { - file.contents.should.be.instanceof(Buffer); - done(); - })); - }); - - it('should match original when result being uncompressed', function(done) { - var id = nid(); - var out = gulp.dest('tmp'); - - out.on('end', function() { - fs.readFile('./tmp/' + id + '.txt.gz', function(err, file) { - zlib.unzip(file, function(err, buffer) { - file = buffer.toString('utf-8', 0, buffer.length); - - fs.readFile('./files/small.txt', { encoding: 'utf-8' }, function(err, original) { - file.should.equal(original); - done(); - }); - }); - }); - }); - - gulp.src('files/small.txt') - .pipe(rename({ basename: id })) - .pipe(gzip()) - .pipe(out); - }); - - it('should handle threshold of 1kb by passing through small.txt (<1kb)', function(done) { - var id = nid(); - var out = gulp.dest('tmp'); - - out.on('end', function() { - fs.readFile('./tmp/' + id + '.txt', { encoding: 'utf-8' }, function(err, file) { - fs.readFile('./files/small.txt', { encoding: 'utf-8' }, function(err, original) { - file.should.equal(original); - done(); - }); - }); - }); - - gulp.src('files/small.txt') - .pipe(rename({ basename: id })) - .pipe(gzip({ threshold: '1kb' })) - .pipe(out); - }); - - it('should handle threshold of 1kb by compressing big.txt (>1kb)', function(done) { - var id = nid(); - var out = gulp.dest('tmp'); - - out.on('end', function() { - fs.readFile('./tmp/' + id + '.txt.gz', function(err, file) { - zlib.unzip(file, function(err, buffer) { - file = buffer.toString('utf-8'); - - fs.readFile('./files/big.txt', { encoding: 'utf-8' }, function(err, original) { - file.should.equal(original); - done(); - }); - }); - }); - }); - - gulp.src('files/big.txt') - .pipe(rename({ basename: id })) - .pipe(gzip({ threshold: '1kb' })) - .pipe(out); - }); - }); - - describe('stream mode', function() { - - it('should create file with .gz extension, by default', function(done) { - var id = nid(); - var out = gulp.dest('tmp'); - - out.on('end', function() { - fs.readFile('./tmp/' + id + '.txt.gz', function(err, file) { - should.not.exist(err); - should.exist(file); - file.should.not.be.empty; - done(); - }); - }); - - gulp.src('files/small.txt', { buffer: false }) - .pipe(rename({ basename: id })) - .pipe(gzip()) - .pipe(out); - }); - - it('should create file without .gz extension when { append: false }', function(done) { - var id = nid(); - var out = gulp.dest('tmp'); - - out.on('end', function() { - fs.readFile('./tmp/' + id + '.txt', function(err, file) { - should.not.exist(err); - should.exist(file); - file.should.not.be.empty; - done(); - }); - }); - - gulp.src('files/small.txt', { buffer: false }) - .pipe(rename({ basename: id })) - .pipe(gzip({ append: false })) - .pipe(out); - }); - - it('should return file contents as a Stream', function(done) { - gulp.src('files/small.txt', { buffer: false }) - .pipe(gzip()) - .pipe(tap(function(file) { - file.contents.should.be.instanceof(Stream); - done(); - })); - }); - - it('should return file contents as a Stream while handling threshold', function(done) { - gulp.src('files/small.txt', { buffer: false }) - .pipe(gzip({ threshold: '1kb' })) - .pipe(tap(function(file) { - file.contents.should.be.instanceof(Stream); - done(); - })); - }); - - it('should match original when result being uncompressed', function(done) { - var id = nid(); - var out = gulp.dest('tmp'); - - out.on('end', function() { - fs.readFile('./tmp/' + id + '.txt.gz', function(err, file) { - zlib.unzip(file, function(err, buffer) { - file = buffer.toString('utf-8', 0, buffer.length); - - fs.readFile('./files/small.txt', { encoding: 'utf-8' }, function(err, original) { - file.should.equal(original); - done(); - }); - }); - }); - }); - - gulp.src('files/small.txt', { buffer: false }) - .pipe(rename({ basename: id })) - .pipe(gzip()) - .pipe(out); - }); - - it('should handle threshold of 1kb by passing through small.txt (<1kb)', function(done) { - var id = nid(); - var out = gulp.dest('tmp'); - - out.on('end', function() { - fs.readFile('./tmp/' + id + '.txt', { encoding: 'utf-8' }, function(err, file) { - fs.readFile('./files/small.txt', { encoding: 'utf-8' }, function(err, original) { - file.should.equal(original); - done(); - }); - }); - }); - - gulp.src('files/small.txt', { buffer: false }) - .pipe(rename({ basename: id })) - .pipe(gzip({ threshold: '1kb' })) - .pipe(out); - }); - - it('should handle threshold of 1kb by compressing big.txt (>1kb)', function(done) { - var id = nid(); - var out = gulp.dest('tmp'); - - out.on('end', function() { - fs.readFile('./tmp/' + id + '.txt.gz', function(err, file) { - zlib.unzip(file, function(err, buffer) { - file = buffer.toString('utf-8'); - - fs.readFile('./files/big.txt', { encoding: 'utf-8' }, function(err, original) { - file.should.equal(original); - done(); - }); - }); - }); - }); - - gulp.src('files/big.txt', { buffer: false }) - .pipe(rename({ basename: id })) - .pipe(gzip({ threshold: '1kb' })) - .pipe(out); - }); - }); - - describe('file properties', function() { - it('should not lose any properties from the Vinyl file', function(done) { - gulp.src('files/small.txt') - .pipe(tap(function(file) { - file.test = 'test'; - })) - .pipe(gzip()) - .pipe(tap(function(file) { - file.should.have.property('test', 'test'); - done(); - })); - }); - - it('should set `contentEncoding`', function(done) { - gulp.src('files/small.txt') - .pipe(gzip()) - .pipe(tap(function(file) { - file.should.have.property('contentEncoding'); - file.contentEncoding.should.containEql('gzip'); - done(); - })); - }); - }); - - describe('gzip options', function() { - - it('should handle compression level in buffer mode', function(done) { - var id_lowest_compression = nid(); - var id_highest_compression = nid(); - - var out_lowest_compression = gulp.dest('tmp'); - var out_highest_compression = gulp.dest('tmp'); - - var size_lowest_compression = 0; - var size_highest_compression = 0; - - out_lowest_compression.on('end', function() { - fs.stat('./tmp/' + id_lowest_compression + '.txt.gz', function (err, stats) { - size_lowest_compression = stats.size; - - if (size_highest_compression > 0) { - size_highest_compression.should.be.lessThan(size_lowest_compression); - done(); - } - }); - }); - - out_highest_compression.on('end', function() { - fs.stat('./tmp/' + id_highest_compression + '.txt.gz', function (err, stats) { - size_highest_compression = stats.size; - - if (size_lowest_compression > 0) { - size_highest_compression.should.be.lessThan(size_lowest_compression); - done(); - } - }); - }); - - gulp.src('files/big.txt') - .pipe(rename({ basename: id_lowest_compression })) - .pipe(gzip({ gzipOptions: { level: 1 } })) - .pipe(out_lowest_compression); - - gulp.src('files/big.txt') - .pipe(rename({ basename: id_highest_compression })) - .pipe(gzip({ gzipOptions: { level: 9 } })) - .pipe(out_highest_compression); - }); - - it('should handle compression level in stream mode', function(done) { - var id_lowest_compression = nid(); - var id_highest_compression = nid(); - - var out_lowest_compression = gulp.dest('tmp'); - var out_highest_compression = gulp.dest('tmp'); - - var size_lowest_compression = 0; - var size_highest_compression = 0; - - out_lowest_compression.on('end', function() { - fs.stat('./tmp/' + id_lowest_compression + '.txt.gz', function (err, stats) { - size_lowest_compression = stats.size; - - if (size_highest_compression > 0) { - size_highest_compression.should.be.lessThan(size_lowest_compression); - done(); - } - }); - }); - - out_highest_compression.on('end', function() { - fs.stat('./tmp/' + id_highest_compression + '.txt.gz', function (err, stats) { - size_highest_compression = stats.size; - - if (size_lowest_compression > 0) { - size_highest_compression.should.be.lessThan(size_lowest_compression); - done(); - } - }); - }); - - gulp.src('files/big.txt', { buffer: false }) - .pipe(rename({ basename: id_lowest_compression })) - .pipe(gzip({ gzipOptions: { level: 1 } })) - .pipe(out_lowest_compression); - - gulp.src('files/big.txt', { buffer: false }) - .pipe(rename({ basename: id_highest_compression })) - .pipe(gzip({ gzipOptions: { level: 9 } })) - .pipe(out_highest_compression); - }); - }); - - }); + describe('plugin level', function() { + + describe('config', function() { + + it('should have default config', function(done) { + var instance = gzip(); + instance.config.should.eql({ append: true, gzipOptions: {}, threshold: false }); + done(); + }); + + it('should merge options with defaults', function(done) { + var instance = gzip({ append: false }); + instance.config.should.eql({ append: false, gzipOptions: {}, threshold: false }); + done(); + }); + + it('should set threshold to false while receiving false', function(done) { + var instance = gzip({ threshold: false }); + instance.config.threshold.should.be.false; + done(); + }); + + it('should set threshold to 150 while receiving true', function(done) { + var instance = gzip({ threshold: true }); + instance.config.threshold.should.eql(150); + done(); + }); + + it('should set threshold to Number while receiving Number', function(done) { + var instance = gzip({ threshold: 1024 }); + instance.config.should.have.property('threshold', 1024); + done(); + }); + + it('should set threshold to 150 while receiving Number < 150', function(done) { + var instance = gzip({ threshold: 100 }); + instance.config.should.have.property('threshold', 150); + done(); + }); + + it('should set threshold to Number while receiving String (bytes result)', function(done) { + var instance = gzip({ threshold: '1kb' }); + instance.config.should.have.property('threshold', 1024); + done(); + }); + + it('should set threshold to 150 while receiving String (bytes result < 150)', function(done) { + var instance = gzip({ threshold: '1kb' }); + instance.config.should.have.property('threshold', 1024); + done(); + }); + + it('should set gzipOptions', function(done) { + var instance = gzip({ gzipOptions: { level: 9, memLevel: 1} }); + instance.config.should.have.property('gzipOptions'); + instance.config.gzipOptions.should.have.property('level', 9); + instance.config.gzipOptions.should.have.property('memLevel', 1); + done(); + }); + }); + }); + + describe('handler level', function() { + + describe('file extension', function() { + + it('should append .gz to the file extension, by default', function(done) { + gulp.src('files/small.txt') + .pipe(gzip()) + .pipe(tap(function(file) { + file.path.should.endWith('.gz'); + done(); + })); + }); + + it('should not append .gz to the file extension receiving { append: false }', function(done) { + gulp.src('files/small.txt') + .pipe(gzip({ append: false })) + .pipe(tap(function(file) { + file.path.should.not.endWith('.gz'); + done(); + })); + }); + }); + + describe('buffer mode', function() { + + it('should create file with .gz extension, by default', function(done) { + var id = nid(); + var out = gulp.dest('tmp'); + + out.on('end', function() { + fs.readFile('./tmp/' + id + '.txt.gz', function(err, file) { + should.not.exist(err); + should.exist(file); + file.should.not.be.empty; + done(); + }); + }); + + gulp.src('files/small.txt') + .pipe(rename({ basename: id })) + .pipe(gzip()) + .pipe(out); + }); + + it('should create file without .gz extension when { append: false }', function(done) { + var id = nid(); + var out = gulp.dest('tmp'); + + out.on('end', function() { + fs.readFile('./tmp/' + id + '.txt', function(err, file) { + should.not.exist(err); + should.exist(file); + file.should.not.be.empty; + done(); + }); + }); + + gulp.src('files/small.txt') + .pipe(rename({ basename: id })) + .pipe(gzip({ append: false })) + .pipe(out); + }); + + it('should return file contents as a Buffer', function(done) { + gulp.src('files/small.txt') + .pipe(gzip()) + .pipe(tap(function(file) { + file.contents.should.be.instanceof(Buffer); + done(); + })); + }); + + it('should return file contents as a Buffer while handling threshold', function(done) { + gulp.src('files/big.txt') + .pipe(gzip({ threshold: '1kb' })) + .pipe(tap(function(file) { + file.contents.should.be.instanceof(Buffer); + done(); + })); + }); + + it('should match original when result being uncompressed', function(done) { + var id = nid(); + var out = gulp.dest('tmp'); + + out.on('end', function() { + fs.readFile('./tmp/' + id + '.txt.gz', function(err, file) { + zlib.unzip(file, function(err, buffer) { + file = buffer.toString('utf-8', 0, buffer.length); + + fs.readFile('./files/small.txt', { encoding: 'utf-8' }, function(err, original) { + file.should.equal(original); + done(); + }); + }); + }); + }); + + gulp.src('files/small.txt') + .pipe(rename({ basename: id })) + .pipe(gzip()) + .pipe(out); + }); + + it('should handle threshold of 1kb by passing through small.txt (<1kb)', function(done) { + var id = nid(); + var out = gulp.dest('tmp'); + + out.on('end', function() { + fs.readFile('./tmp/' + id + '.txt', { encoding: 'utf-8' }, function(err, file) { + fs.readFile('./files/small.txt', { encoding: 'utf-8' }, function(err, original) { + file.should.equal(original); + done(); + }); + }); + }); + + gulp.src('files/small.txt') + .pipe(rename({ basename: id })) + .pipe(gzip({ threshold: '1kb' })) + .pipe(out); + }); + + it('should handle threshold of 1kb by compressing big.txt (>1kb)', function(done) { + var id = nid(); + var out = gulp.dest('tmp'); + + out.on('end', function() { + fs.readFile('./tmp/' + id + '.txt.gz', function(err, file) { + zlib.unzip(file, function(err, buffer) { + file = buffer.toString('utf-8'); + + fs.readFile('./files/big.txt', { encoding: 'utf-8' }, function(err, original) { + file.should.equal(original); + done(); + }); + }); + }); + }); + + gulp.src('files/big.txt') + .pipe(rename({ basename: id })) + .pipe(gzip({ threshold: '1kb' })) + .pipe(out); + }); + }); + + describe('stream mode', function() { + + it('should create file with .gz extension, by default', function(done) { + var id = nid(); + var out = gulp.dest('tmp'); + + out.on('end', function() { + fs.readFile('./tmp/' + id + '.txt.gz', function(err, file) { + should.not.exist(err); + should.exist(file); + file.should.not.be.empty; + done(); + }); + }); + + gulp.src('files/small.txt', { buffer: false }) + .pipe(rename({ basename: id })) + .pipe(gzip()) + .pipe(out); + }); + + it('should create file without .gz extension when { append: false }', function(done) { + var id = nid(); + var out = gulp.dest('tmp'); + + out.on('end', function() { + fs.readFile('./tmp/' + id + '.txt', function(err, file) { + should.not.exist(err); + should.exist(file); + file.should.not.be.empty; + done(); + }); + }); + + gulp.src('files/small.txt', { buffer: false }) + .pipe(rename({ basename: id })) + .pipe(gzip({ append: false })) + .pipe(out); + }); + + it('should return file contents as a Stream', function(done) { + gulp.src('files/small.txt', { buffer: false }) + .pipe(gzip()) + .pipe(tap(function(file) { + file.contents.should.be.instanceof(Stream); + done(); + })); + }); + + it('should return file contents as a Stream while handling threshold', function(done) { + gulp.src('files/small.txt', { buffer: false }) + .pipe(gzip({ threshold: '1kb' })) + .pipe(tap(function(file) { + file.contents.should.be.instanceof(Stream); + done(); + })); + }); + + it('should match original when result being uncompressed', function(done) { + var id = nid(); + var out = gulp.dest('tmp'); + + out.on('end', function() { + fs.readFile('./tmp/' + id + '.txt.gz', function(err, file) { + zlib.unzip(file, function(err, buffer) { + file = buffer.toString('utf-8', 0, buffer.length); + + fs.readFile('./files/small.txt', { encoding: 'utf-8' }, function(err, original) { + file.should.equal(original); + done(); + }); + }); + }); + }); + + gulp.src('files/small.txt', { buffer: false }) + .pipe(rename({ basename: id })) + .pipe(gzip()) + .pipe(out); + }); + + it('should handle threshold of 1kb by passing through small.txt (<1kb)', function(done) { + var id = nid(); + var out = gulp.dest('tmp'); + + out.on('end', function() { + fs.readFile('./tmp/' + id + '.txt', { encoding: 'utf-8' }, function(err, file) { + fs.readFile('./files/small.txt', { encoding: 'utf-8' }, function(err, original) { + file.should.equal(original); + done(); + }); + }); + }); + + gulp.src('files/small.txt', { buffer: false }) + .pipe(rename({ basename: id })) + .pipe(gzip({ threshold: '1kb' })) + .pipe(out); + }); + + it('should handle threshold of 1kb by compressing big.txt (>1kb)', function(done) { + var id = nid(); + var out = gulp.dest('tmp'); + + out.on('end', function() { + fs.readFile('./tmp/' + id + '.txt.gz', function(err, file) { + zlib.unzip(file, function(err, buffer) { + file = buffer.toString('utf-8'); + + fs.readFile('./files/big.txt', { encoding: 'utf-8' }, function(err, original) { + file.should.equal(original); + done(); + }); + }); + }); + }); + + gulp.src('files/big.txt', { buffer: false }) + .pipe(rename({ basename: id })) + .pipe(gzip({ threshold: '1kb' })) + .pipe(out); + }); + }); + + describe('file properties', function() { + it('should not lose any properties from the Vinyl file', function(done) { + gulp.src('files/small.txt') + .pipe(tap(function(file) { + file.test = 'test'; + })) + .pipe(gzip()) + .pipe(tap(function(file) { + file.should.have.property('test', 'test'); + done(); + })); + }); + + it('should set `contentEncoding`', function(done) { + gulp.src('files/small.txt') + .pipe(gzip()) + .pipe(tap(function(file) { + file.should.have.property('contentEncoding'); + file.contentEncoding.should.containEql('gzip'); + done(); + })); + }); + }); + + describe('gzip options', function() { + + it('should handle compression level in buffer mode', function(done) { + var id_lowest_compression = nid(); + var id_highest_compression = nid(); + + var out_lowest_compression = gulp.dest('tmp'); + var out_highest_compression = gulp.dest('tmp'); + + var size_lowest_compression = 0; + var size_highest_compression = 0; + + out_lowest_compression.on('end', function() { + fs.stat('./tmp/' + id_lowest_compression + '.txt.gz', function (err, stats) { + size_lowest_compression = stats.size; + + if (size_highest_compression > 0) { + size_highest_compression.should.be.lessThan(size_lowest_compression); + done(); + } + }); + }); + + out_highest_compression.on('end', function() { + fs.stat('./tmp/' + id_highest_compression + '.txt.gz', function (err, stats) { + size_highest_compression = stats.size; + + if (size_lowest_compression > 0) { + size_highest_compression.should.be.lessThan(size_lowest_compression); + done(); + } + }); + }); + + gulp.src('files/big.txt') + .pipe(rename({ basename: id_lowest_compression })) + .pipe(gzip({ gzipOptions: { level: 1 } })) + .pipe(out_lowest_compression); + + gulp.src('files/big.txt') + .pipe(rename({ basename: id_highest_compression })) + .pipe(gzip({ gzipOptions: { level: 9 } })) + .pipe(out_highest_compression); + }); + + it('should handle compression level in stream mode', function(done) { + var id_lowest_compression = nid(); + var id_highest_compression = nid(); + + var out_lowest_compression = gulp.dest('tmp'); + var out_highest_compression = gulp.dest('tmp'); + + var size_lowest_compression = 0; + var size_highest_compression = 0; + + out_lowest_compression.on('end', function() { + fs.stat('./tmp/' + id_lowest_compression + '.txt.gz', function (err, stats) { + size_lowest_compression = stats.size; + + if (size_highest_compression > 0) { + size_highest_compression.should.be.lessThan(size_lowest_compression); + done(); + } + }); + }); + + out_highest_compression.on('end', function() { + fs.stat('./tmp/' + id_highest_compression + '.txt.gz', function (err, stats) { + size_highest_compression = stats.size; + + if (size_lowest_compression > 0) { + size_highest_compression.should.be.lessThan(size_lowest_compression); + done(); + } + }); + }); + + gulp.src('files/big.txt', { buffer: false }) + .pipe(rename({ basename: id_lowest_compression })) + .pipe(gzip({ gzipOptions: { level: 1 } })) + .pipe(out_lowest_compression); + + gulp.src('files/big.txt', { buffer: false }) + .pipe(rename({ basename: id_highest_compression })) + .pipe(gzip({ gzipOptions: { level: 9 } })) + .pipe(out_highest_compression); + }); + }); + + }); });