"use strict"; var vows = require('vows') , async = require('async') , assert = require('assert') , events = require('events') , fs = require('fs') , semver = require('semver') , streams , RollingFileStream; if (semver.satisfies(process.version, '>=0.10.0')) { streams = require('stream'); } else { streams = require('readable-stream'); } RollingFileStream = require('../../lib/streams').RollingFileStream; function remove(filename) { try { fs.unlinkSync(filename); } catch (e) { //doesn't really matter if it failed } } function create(filename) { fs.writeFileSync(filename, "test file"); } vows.describe('RollingFileStream').addBatch({ 'arguments': { topic: function() { remove(__dirname + "/test-rolling-file-stream"); return new RollingFileStream("test-rolling-file-stream", 1024, 5); }, 'should take a filename, file size (bytes), no. backups, return Writable': function(stream) { assert.instanceOf(stream, streams.Writable); assert.equal(stream.filename, "test-rolling-file-stream"); assert.equal(stream.size, 1024); assert.equal(stream.backups, 5); }, 'with default settings for the underlying stream': function(stream) { assert.equal(stream.theStream.mode, 420); assert.equal(stream.theStream.flags, 'a'); //encoding isn't a property on the underlying stream //assert.equal(stream.theStream.encoding, 'utf8'); } }, 'with stream arguments': { topic: function() { remove(__dirname + '/test-rolling-file-stream'); return new RollingFileStream( 'test-rolling-file-stream', 1024, 5, { mode: parseInt('0666', 8) } ); }, 'should pass them to the underlying stream': function(stream) { assert.equal(stream.theStream.mode, parseInt('0666', 8)); } }, 'without size': { topic: function() { try { new RollingFileStream(__dirname + "/test-rolling-file-stream"); } catch (e) { return e; } }, 'should throw an error': function(err) { assert.instanceOf(err, Error); } }, 'without number of backups': { topic: function() { remove('test-rolling-file-stream'); return new RollingFileStream(__dirname + "/test-rolling-file-stream", 1024); }, 'should default to 1 backup': function(stream) { assert.equal(stream.backups, 1); } }, 'writing less than the file size': { topic: function() { remove(__dirname + "/test-rolling-file-stream-write-less"); var that = this , stream = new RollingFileStream( __dirname + "/test-rolling-file-stream-write-less", 100 ); stream.write("cheese", "utf8", function() { stream.end(); fs.readFile(__dirname + "/test-rolling-file-stream-write-less", "utf8", that.callback); }); }, 'should write to the file': function(contents) { assert.equal(contents, "cheese"); }, 'the number of files': { topic: function() { fs.readdir(__dirname, this.callback); }, 'should be one': function(files) { assert.equal( files.filter( function(file) { return file.indexOf('test-rolling-file-stream-write-less') > -1; } ).length, 1 ); } } }, 'writing more than the file size': { topic: function() { remove(__dirname + "/test-rolling-file-stream-write-more"); remove(__dirname + "/test-rolling-file-stream-write-more.1"); var that = this , stream = new RollingFileStream( __dirname + "/test-rolling-file-stream-write-more", 45 ); async.forEach( [0, 1, 2, 3, 4, 5, 6], function(i, cb) { stream.write(i +".cheese\n", "utf8", cb); }, function() { stream.end(); that.callback(); } ); }, 'the number of files': { topic: function() { fs.readdir(__dirname, this.callback); }, 'should be two': function(files) { assert.equal(files.filter( function(file) { return file.indexOf('test-rolling-file-stream-write-more') > -1; } ).length, 2); } }, 'the first file': { topic: function() { fs.readFile(__dirname + "/test-rolling-file-stream-write-more", "utf8", this.callback); }, 'should contain the last two log messages': function(contents) { assert.equal(contents, '5.cheese\n6.cheese\n'); } }, 'the second file': { topic: function() { fs.readFile(__dirname + '/test-rolling-file-stream-write-more.1', "utf8", this.callback); }, 'should contain the first five log messages': function(contents) { assert.equal(contents, '0.cheese\n1.cheese\n2.cheese\n3.cheese\n4.cheese\n'); } } }, 'when many files already exist': { topic: function() { remove(__dirname + '/test-rolling-stream-with-existing-files.11'); remove(__dirname + '/test-rolling-stream-with-existing-files.20'); remove(__dirname + '/test-rolling-stream-with-existing-files.-1'); remove(__dirname + '/test-rolling-stream-with-existing-files.1.1'); remove(__dirname + '/test-rolling-stream-with-existing-files.1'); create(__dirname + '/test-rolling-stream-with-existing-files.11'); create(__dirname + '/test-rolling-stream-with-existing-files.20'); create(__dirname + '/test-rolling-stream-with-existing-files.-1'); create(__dirname + '/test-rolling-stream-with-existing-files.1.1'); create(__dirname + '/test-rolling-stream-with-existing-files.1'); var that = this , stream = new RollingFileStream( __dirname + "/test-rolling-stream-with-existing-files", 45, 5 ); async.forEach( [0, 1, 2, 3, 4, 5, 6], function(i, cb) { stream.write(i +".cheese\n", "utf8", cb); }, function() { stream.end(); that.callback(); } ); }, 'the files': { topic: function() { fs.readdir(__dirname, this.callback); }, 'should be rolled': function(files) { assert.include(files, 'test-rolling-stream-with-existing-files'); assert.include(files, 'test-rolling-stream-with-existing-files.1'); assert.include(files, 'test-rolling-stream-with-existing-files.2'); assert.include(files, 'test-rolling-stream-with-existing-files.11'); assert.include(files, 'test-rolling-stream-with-existing-files.20'); } } } }).exportTo(module);