diff --git a/Gruntfile.js b/Gruntfile.js index 3a94db3..2b5569d 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -27,6 +27,17 @@ module.exports = function(grunt) { clean: { test: ['tmp'] }, + + copy: { + gzipSrcEqualDest: { + files: [{ + expand : true, + cwd : 'test/fixtures', + src : '**/*.js', + dest : 'tmp/gzipSrcEqualDest' + }] + } + }, // Configuration to be run (and then tested). compress: { @@ -72,6 +83,14 @@ module.exports = function(grunt) { {expand: true, cwd: 'test/fixtures', src: ['**/*.js'], dest: 'tmp/gzipCustomExt/', ext: '.gz.js'} ] }, + gzipSrcEqualDest: { + options: { + mode: 'gzip' + }, + files: [ + {expand: true, cwd: 'tmp/gzipSrcEqualDest', src: ['**/*.js'], dest: 'tmp/gzipSrcEqualDest/', ext: '.js'} + ] + }, gzip: { expand: true, cwd: 'test/fixtures/', @@ -122,12 +141,13 @@ module.exports = function(grunt) { // These plugins provide necessary tasks. grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-clean'); + grunt.loadNpmTasks('grunt-contrib-copy'); grunt.loadNpmTasks('grunt-contrib-nodeunit'); grunt.loadNpmTasks('grunt-contrib-internal'); // Whenever the "test" task is run, first clean the "tmp" dir, then run this // plugin's task(s), then test the result. - grunt.registerTask('test', ['jshint', 'clean', 'compress', 'nodeunit']); + grunt.registerTask('test', ['jshint', 'clean', 'copy', 'compress', 'nodeunit']); // By default, lint and run all tests. grunt.registerTask('default', ['test', 'build-contrib']); diff --git a/package.json b/package.json index 6b4d90b..4f511a0 100644 --- a/package.json +++ b/package.json @@ -18,12 +18,14 @@ "dependencies": { "archiver": "^0.21.0", "chalk": "^1.1.1", - "pretty-bytes": "^3.0.1" + "pretty-bytes": "^3.0.1", + "stream-buffers": "^2.1.0" }, "devDependencies": { "grunt": "^0.4.5", "grunt-cli": "^0.1.13", "grunt-contrib-clean": "^1.0.0", + "grunt-contrib-copy": "^0.7.0", "grunt-contrib-internal": "^0.4.2", "grunt-contrib-jshint": "^0.11.0", "grunt-contrib-nodeunit": "^0.4.1", diff --git a/tasks/lib/compress.js b/tasks/lib/compress.js index eeb5c80..4f6abbb 100644 --- a/tasks/lib/compress.js +++ b/tasks/lib/compress.js @@ -14,6 +14,7 @@ var prettyBytes = require('pretty-bytes'); var chalk = require('chalk'); var zlib = require('zlib'); var archiver = require('archiver'); +var streamBuffers = require('stream-buffers'); module.exports = function(grunt) { @@ -65,7 +66,35 @@ module.exports = function(grunt) { grunt.file.mkdir(path.dirname(filePair.dest)); var srcStream = fs.createReadStream(src); - var destStream = fs.createWriteStream(filePair.dest); + var originalSize = exports.getSize(src); + + var destStream; + function init_destStream() { + destStream = fs.createWriteStream(filePair.dest); + + destStream.on('close', function() { + var compressedSize = exports.getSize(filePair.dest); + var ratio = Math.round(parseInt(compressedSize) / parseInt(originalSize) * 100) + '%'; + + grunt.log.writeln('Created ' + chalk.cyan(filePair.dest) + ' (' + compressedSize + ') - ' + chalk.cyan(ratio) + ' of the original size'); + nextFile(); + }); + } + + // write to memory stream if source and destination are the same + var tmpStream; + if (src === filePair.dest) { + tmpStream = new streamBuffers.WritableStreamBuffer(); + tmpStream.on('close', function() { + init_destStream(); + + destStream.write(this.getContents()); + destStream.end(); + }); + } else { + init_destStream(); + } + var compressor = algorithm.call(zlib, exports.options); compressor.on('error', function(err) { @@ -74,16 +103,7 @@ module.exports = function(grunt) { nextFile(); }); - destStream.on('close', function() { - var originalSize = exports.getSize(src); - var compressedSize = exports.getSize(filePair.dest); - var ratio = Math.round(parseInt(compressedSize, 10) / parseInt(originalSize, 10) * 100) + '%'; - - grunt.verbose.writeln('Created ' + chalk.cyan(filePair.dest) + ' (' + compressedSize + ') - ' + chalk.cyan(ratio) + ' of the original size'); - nextFile(); - }); - - srcStream.pipe(compressor).pipe(destStream); + srcStream.pipe(compressor).pipe(tmpStream || destStream); }, nextPair); }, done); }; diff --git a/test/compress_test.js b/test/compress_test.js index 3d49bb1..d254606 100644 --- a/test/compress_test.js +++ b/test/compress_test.js @@ -122,6 +122,26 @@ exports.compress = { }); test.done(); }, + gzipSrcEqualDest: function(test) { + test.expect(3); + grunt.util.async.forEachSeries([ + 'test.js', + path.join('folder_one', 'one.js'), + path.join('folder_two', 'two.js'), + ], function(file, next) { + var expected = grunt.file.read(path.join('test', 'fixtures', file)); + var actual = ''; + fs.createReadStream(path.join('tmp', 'gzipSrcEqualDest', file)) + .pipe(zlib.createGunzip()) + .on('data', function(buf) { + actual += buf.toString(); + }) + .on('end', function() { + test.equal(actual, expected, 'should be equal to fixture after gunzipping'); + next(); + }); + }, test.done); + }, deflate: function(test) { test.expect(3); grunt.util.async.forEachSeries([