summaryrefslogtreecommitdiff
path: root/node_modules/winston/test
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/winston/test')
-rw-r--r--node_modules/winston/test/helpers.js256
-rw-r--r--node_modules/winston/test/transports/console-test.js202
-rw-r--r--node_modules/winston/test/transports/file-archive-test.js83
-rw-r--r--node_modules/winston/test/transports/file-maxfiles-test.js102
-rw-r--r--node_modules/winston/test/transports/file-maxsize-test.js82
-rw-r--r--node_modules/winston/test/transports/file-open-test.js57
-rw-r--r--node_modules/winston/test/transports/file-stress-test.js72
-rw-r--r--node_modules/winston/test/transports/file-tailrolling-test.js92
-rw-r--r--node_modules/winston/test/transports/file-test.js134
-rw-r--r--node_modules/winston/test/transports/http-test.js70
-rw-r--r--node_modules/winston/test/transports/memory-test.js31
-rw-r--r--node_modules/winston/test/transports/transport.js212
12 files changed, 1393 insertions, 0 deletions
diff --git a/node_modules/winston/test/helpers.js b/node_modules/winston/test/helpers.js
new file mode 100644
index 0000000..8575fb6
--- /dev/null
+++ b/node_modules/winston/test/helpers.js
@@ -0,0 +1,256 @@
+/*
+ * helpers.js: Test helpers for winston
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENSE
+ *
+ */
+
+var assert = require('assert'),
+ fs = require('fs'),
+ path = require('path'),
+ spawn = require('child_process').spawn,
+ util = require('util'),
+ vows = require('vows'),
+ winston = require('../lib/winston');
+
+var helpers = exports;
+
+helpers.size = function (obj) {
+ var size = 0, key;
+ for (key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ size++;
+ }
+ }
+
+ return size;
+};
+
+helpers.tryUnlink = function (file) {
+ try { fs.unlinkSync(file) }
+ catch (ex) { }
+};
+
+helpers.assertDateInfo = function (info) {
+ assert.isNumber(Date.parse(info));
+};
+
+helpers.assertProcessInfo = function (info) {
+ assert.isNumber(info.pid);
+ assert.isNumber(info.uid);
+ assert.isNumber(info.gid);
+ assert.isString(info.cwd);
+ assert.isString(info.execPath);
+ assert.isString(info.version);
+ assert.isArray(info.argv);
+ assert.isObject(info.memoryUsage);
+};
+
+helpers.assertOsInfo = function (info) {
+ assert.isArray(info.loadavg);
+ assert.isNumber(info.uptime);
+};
+
+helpers.assertTrace = function (trace) {
+ trace.forEach(function (site) {
+ assert.isTrue(!site.column || typeof site.column === 'number');
+ assert.isTrue(!site.line || typeof site.line === 'number');
+ assert.isTrue(!site.file || typeof site.file === 'string');
+ assert.isTrue(!site.method || typeof site.method === 'string');
+ assert.isTrue(!site.function || typeof site.function === 'string');
+ assert.isTrue(typeof site.native === 'boolean');
+ });
+};
+
+helpers.assertLogger = function (logger, level) {
+ assert.instanceOf(logger, winston.Logger);
+ assert.isFunction(logger.log);
+ assert.isFunction(logger.add);
+ assert.isFunction(logger.remove);
+ assert.equal(logger.level, level || "info");
+ Object.keys(logger.levels).forEach(function (method) {
+ assert.isFunction(logger[method]);
+ });
+};
+
+helpers.assertConsole = function (transport) {
+ assert.instanceOf(transport, winston.transports.Console);
+ assert.isFunction(transport.log);
+};
+
+helpers.assertMemory = function (transport) {
+ assert.instanceOf(transport, winston.transports.Memory);
+ assert.isFunction(transport.log);
+};
+
+helpers.assertFile = function (transport) {
+ assert.instanceOf(transport, winston.transports.File);
+ assert.isFunction(transport.log);
+};
+
+helpers.assertCouchdb = function (transport) {
+ assert.instanceOf(transport, winston.transports.Couchdb);
+ assert.isFunction(transport.log);
+};
+
+helpers.assertHandleExceptions = function (options) {
+ return {
+ topic: function () {
+ var that = this,
+ child = spawn('node', [options.script]);
+
+ helpers.tryUnlink(options.logfile);
+ child.on('exit', function () {
+ fs.readFile(options.logfile, that.callback);
+ });
+ },
+ "should save the error information to the specified file": function (err, data) {
+ assert.isTrue(!err);
+ data = JSON.parse(data);
+
+ assert.isObject(data);
+ helpers.assertProcessInfo(data.process);
+ helpers.assertOsInfo(data.os);
+ helpers.assertTrace(data.trace);
+ if (options.message) {
+ assert.equal('uncaughtException: ' + options.message, data.message);
+ }
+ }
+ };
+};
+
+helpers.assertFailedTransport = function (transport) {
+ return {
+ topic: function () {
+ var self = this;
+ transport.on('error', function(emitErr){
+ transport.log('error', 'test message 2', {}, function(logErr, logged){
+ self.callback(emitErr, logErr);
+ });
+ });
+ transport.log('error', 'test message');
+ },
+ "should emit an error": function (emitErr, logErr) {
+ assert.instanceOf(emitErr, Error);
+ assert.equal(emitErr.code, 'ENOENT');
+ },
+ "should enter noop failed state": function (emitErr, logErr) {
+ assert.instanceOf(logErr, Error);
+ assert.equal(transport._failures, transport.maxRetries);
+ }
+ };
+};
+
+helpers.testNpmLevels = function (transport, assertMsg, assertFn) {
+ return helpers.testLevels(winston.config.npm.levels, transport, assertMsg, assertFn);
+};
+
+helpers.testSyslogLevels = function (transport, assertMsg, assertFn) {
+ return helpers.testLevels(winston.config.syslog.levels, transport, assertMsg, assertFn);
+};
+
+helpers.testLevels = function (levels, transport, assertMsg, assertFn) {
+ var tests = {};
+
+ Object.keys(levels).forEach(function (level) {
+ var test = {
+ topic: function () {
+ transport.log(level, 'test message', {}, this.callback.bind(this, null));
+ }
+ };
+
+ test[assertMsg] = assertFn;
+ tests['with the ' + level + ' level'] = test;
+ });
+
+ var metadatatest = {
+ topic: function () {
+ transport.log('info', 'test message', { metadata: true }, this.callback.bind(this, null));
+ }
+ };
+
+ metadatatest[assertMsg] = assertFn;
+ tests['when passed metadata'] = metadatatest;
+
+ var primmetadatatest = {
+ topic: function () {
+ transport.log('info', 'test message', 'metadata', this.callback.bind(this, null));
+ }
+ };
+
+ primmetadatatest[assertMsg] = assertFn;
+ tests['when passed primitive metadata'] = primmetadatatest;
+
+ var circmetadata = { };
+ circmetadata['metadata'] = circmetadata;
+
+ var circmetadatatest = {
+ topic: function () {
+ transport.log('info', 'test message', circmetadata, this.callback.bind(this, null));
+ }
+ };
+
+ circmetadatatest[assertMsg] = assertFn;
+ tests['when passed circular metadata'] = circmetadatatest;
+
+ return tests;
+};
+
+helpers.assertOptionsThrow = function (options, errMsg) {
+ return function () {
+ assert.throws(
+ function () {
+ try {
+ new (winston.transports.Console)(options);
+ } catch (err) {
+ throw(err);
+ }
+ },
+ new RegExp('^' + errMsg.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + '$')
+ );
+ }
+};
+
+helpers.assertStderrLevels = function (transport, stderrLevels) {
+ return function () {
+ assert.equal(
+ JSON.stringify(Object.keys(transport.stderrLevels).sort()),
+ JSON.stringify(stderrLevels.sort())
+ );
+ }
+};
+
+helpers.testLoggingToStreams = function (levels, transport, stderrLevels, stdMocks) {
+ return {
+ topic: function () {
+ stdMocks.use();
+ transport.showLevel = true;
+ Object.keys(levels).forEach(function (level) {
+ transport.log(
+ level,
+ level + ' should go to ' + (stderrLevels.indexOf(level) > -1 ? 'stderr' : 'stdout'),
+ {},
+ function () {}
+ );
+ });
+ var output = stdMocks.flush();
+ stdMocks.restore();
+ this.callback(null, output, levels);
+ },
+ "output should go to the appropriate streams": function (ign, output, levels) {
+ var outCount = 0,
+ errCount = 0;
+ Object.keys(levels).forEach(function (level) {
+ var line;
+ if (stderrLevels.indexOf(level) > -1) {
+ line = output.stderr[errCount++];
+ assert.equal(line, level + ': ' + level + ' should go to stderr\n');
+ } else {
+ line = output.stdout[outCount++];
+ assert.equal(line, level + ': ' + level + ' should go to stdout\n');
+ }
+ });
+ }
+ }
+};
diff --git a/node_modules/winston/test/transports/console-test.js b/node_modules/winston/test/transports/console-test.js
new file mode 100644
index 0000000..de868b3
--- /dev/null
+++ b/node_modules/winston/test/transports/console-test.js
@@ -0,0 +1,202 @@
+/*
+ * console-test.js: Tests for instances of the Console transport
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENSE
+ *
+ */
+
+var path = require('path'),
+ vows = require('vows'),
+ assert = require('assert'),
+ winston = require('../../lib/winston'),
+ helpers = require('../helpers'),
+ stdMocks = require('std-mocks');
+
+var npmTransport = new (winston.transports.Console)(),
+ syslogTransport = new (winston.transports.Console)({ levels: winston.config.syslog.levels }),
+ alignTransport = new (winston.transports.Console)({ showLevel: true, align: true }),
+ defaultTransport = new (winston.transports.Console)(),
+ rawTransport = new (winston.transports.Console)({ level: 'verbose', raw: true }),
+ debugStdoutTransport = new (winston.transports.Console)({ debugStdout: true }),
+ stderrLevelsTransport = new (winston.transports.Console)({ stderrLevels: ['info', 'warn'] }),
+ customLevels = {
+ alpha: 0,
+ beta: 1,
+ gamma: 2,
+ delta: 3,
+ epsilon: 4,
+ },
+ customLevelsAndStderrTransport = new (winston.transports.Console)({
+ levels: customLevels,
+ stderrLevels: ['delta', 'epsilon']
+ }),
+ noStderrTransport = new (winston.transports.Console)({ stderrLevels: [] });
+
+vows.describe('winston/transports/console').addBatch({
+ "An instance of the Console Transport": {
+ "with showLevel off": {
+ topic : function() {
+ npmTransport.showLevel = false;
+ stdMocks.use();
+ npmTransport.log('info', 'Le message', { meta: true }, this.callback);
+ },
+ "should not have level prepended": function () {
+ stdMocks.restore();
+ var output = stdMocks.flush(),
+ line = output.stdout[0];
+
+ assert.equal(line, 'Le message meta=true\n');
+ }
+ }
+ }
+}).addBatch({
+ "An instance of the Console Transport": {
+ "with showLevel on": {
+ topic : function() {
+ npmTransport.showLevel = true;
+ stdMocks.use();
+ npmTransport.log('info', '');
+ },
+ "should have level prepended": function () {
+ stdMocks.restore();
+ var output = stdMocks.flush(),
+ line = output.stdout[0];
+
+ assert.equal(line, 'info: \n');
+ }
+ },
+ }
+}).addBatch({
+ "An instance of the Console Transport": {
+ "with npm levels": {
+ "should have the proper methods defined": function () {
+ helpers.assertConsole(npmTransport);
+ },
+ "the log() method": helpers.testNpmLevels(npmTransport, "should respond with true", function (ign, err, logged) {
+ assert.isNull(err);
+ assert.isTrue(logged);
+ })
+ },
+ "with syslog levels": {
+ "should have the proper methods defined": function () {
+ helpers.assertConsole(syslogTransport);
+ },
+ "the log() method": helpers.testSyslogLevels(syslogTransport, "should respond with true", function (ign, err, logged) {
+ assert.isNull(err);
+ assert.isTrue(logged);
+ })
+ },
+ "with end-of-line": {
+ topic : function() {
+ npmTransport.eol = 'X';
+ stdMocks.use();
+ npmTransport.log('info', 'Le message', { meta: true }, this.callback);
+ },
+ "should have end-of-line character appended": function () {
+ stdMocks.restore();
+ var output = stdMocks.flush(),
+ line = output.stdout[0];
+ console.dir(line);
+
+ assert.equal(line, 'info: Le message meta=trueX');
+ }
+ }
+ }
+}).addBatch({
+ "An instance of the Console Transport with the align option on": {
+ topic : function() {
+ stdMocks.use();
+ alignTransport.log('info', '');
+ },
+ "should have logs aligned": function () {
+ stdMocks.restore();
+ var output = stdMocks.flush(),
+ line = output.stdout[0];
+
+ assert.equal(line, 'info\011: \n');
+ }
+ }
+}).addBatch({
+ "with align off": {
+ topic : function() {
+ alignTransport.align = false;
+ stdMocks.use();
+ alignTransport.log('info', '');
+ },
+ "should not have logs aligned": function () {
+ stdMocks.restore();
+ var output = stdMocks.flush(),
+ line = output.stdout[0];
+
+ assert.equal(line, 'info: \n');
+ }
+ }
+}).addBatch({
+ 'An instance of a raw Console transport': {
+ 'logging to stdout': {
+ topic: function () {
+ stdMocks.use();
+ rawTransport.log('verbose', 'hello there');
+ }, 'should output json with message property': function () {
+ stdMocks.restore();
+ var output = stdMocks.flush();
+ assert.ok(output.stdout[0].indexOf('"message":"hello there"') > -1);
+ }
+ }
+ }
+}).addBatch({
+ "An instance of the Console Transport with no options": {
+ "should set stderrLevels to 'error' and 'debug' by default": helpers.assertStderrLevels(
+ defaultTransport,
+ ['error', 'debug']
+ ),
+ "should log only 'error' and 'debug' to stderr": helpers.testLoggingToStreams(
+ winston.config.npm.levels, defaultTransport, ['debug', 'error'], stdMocks
+ )
+ }
+}).addBatch({
+ "An instance of the Console Transport with debugStdout set": {
+ "should throw an Error if stderrLevels is set": helpers.assertOptionsThrow(
+ { debugStdout: true, stderrLevels: ['debug'] },
+ "Error: Cannot set debugStdout and stderrLevels together"
+ ),
+ "should set stderrLevels to 'error' by default": helpers.assertStderrLevels(
+ debugStdoutTransport,
+ ['error']
+ ),
+ "should log only the 'error' level to stderr": helpers.testLoggingToStreams(
+ winston.config.npm.levels, debugStdoutTransport, ['error'], stdMocks
+ )
+ }
+}).addBatch({
+ "An instance of the Console Transport with stderrLevels set": {
+ "should throw an Error if stderrLevels is set but not an Array": helpers.assertOptionsThrow(
+ { debugStdout: false, stderrLevels: new String('Not an Array') },
+ "Error: Cannot set stderrLevels to type other than Array"
+ ),
+ "should throw an Error if stderrLevels contains non-string elements": helpers.assertOptionsThrow(
+ { debugStdout: false, stderrLevels: ["good", /^invalid$/, "valid"] },
+ "Error: Cannot have non-string elements in stderrLevels Array"
+ ),
+ "should correctly set stderrLevels": helpers.assertStderrLevels(
+ stderrLevelsTransport,
+ ['info', 'warn']
+ ),
+ "should log only the levels in stderrLevels to stderr": helpers.testLoggingToStreams(
+ winston.config.npm.levels, stderrLevelsTransport, ['info', 'warn'], stdMocks
+ )
+ }
+}).addBatch({
+ "An instance of the Console Transport with stderrLevels set to an empty array": {
+ "should log only to stdout, and not to stderr": helpers.testLoggingToStreams(
+ winston.config.npm.levels, noStderrTransport, [], stdMocks
+ )
+ }
+}).addBatch({
+ "An instance of the Console Transport with custom levels and stderrLevels set": {
+ "should log only the levels in stderrLevels to stderr": helpers.testLoggingToStreams(
+ customLevels, customLevelsAndStderrTransport, ['delta', 'epsilon'], stdMocks
+ )
+ }
+}).export(module);
diff --git a/node_modules/winston/test/transports/file-archive-test.js b/node_modules/winston/test/transports/file-archive-test.js
new file mode 100644
index 0000000..d076ce0
--- /dev/null
+++ b/node_modules/winston/test/transports/file-archive-test.js
@@ -0,0 +1,83 @@
+/*
+ * file-archive-test.js: Tests for instances of the File transport setting the archive option,
+ *
+ * (C) 2015 Nimrod Becker
+ * MIT LICENSE
+ *
+ */
+
+var assert = require('assert'),
+ exec = require('child_process').exec,
+ fs = require('fs'),
+ path = require('path'),
+ vows = require('vows'),
+ winston = require('../../lib/winston'),
+ helpers = require('../helpers');
+
+var archiveTransport = new winston.transports.File({
+ timestamp: true,
+ json: false,
+ zippedArchive: true,
+ tailable: true,
+ filename: 'testarchive.log',
+ dirname: path.join(__dirname, '..', 'fixtures', 'logs'),
+ maxsize: 4096,
+ maxFiles: 3
+});
+
+function data(ch) {
+ return new Array(1018).join(String.fromCharCode(65 + ch));
+}
+
+function logKbytes(kbytes, txt) {
+ //
+ // With no timestamp and at the info level,
+ // winston adds exactly 7 characters:
+ // [info](4)[ :](2)[\n](1)
+ //
+ for (var i = 0; i < kbytes; i++) {
+ archiveTransport.log('info', data(txt), null, function() {});
+ }
+}
+
+vows.describe('winston/transports/file/zippedArchive').addBatch({
+ "An instance of the File Transport with tailable true": {
+ "when created archived files are rolled": {
+ topic: function() {
+ var that = this,
+ created = 0;
+
+ archiveTransport.on('logged', function() {
+ if (++created === 6) {
+ return that.callback();
+ }
+
+ logKbytes(4, created);
+ });
+
+ logKbytes(4, created);
+ },
+ "should be only 3 files called testarchive.log, testarchive1.log.gz and testarchive2.log.gz": function() {
+ //Give the archive a little time to settle
+ // setTimeout(function() {
+ for (var num = 0; num < 6; num++) {
+ var file = !num ? 'testarchive.log' : 'testarchive' + num + '.log.gz',
+ fullpath = path.join(__dirname, '..', 'fixtures', 'logs', file);
+
+ // There should be no files with that name
+ if (num >= 3) {
+ assert.throws(function() {
+ fs.statSync(fullpath);
+ }, Error);
+ } else {
+ // The other files should exist
+ assert.doesNotThrow(function() {
+ fs.statSync(fullpath);
+ }, Error);
+ }
+ }
+ //},5000);
+ },
+ }
+ },
+}).export(module);
diff --git a/node_modules/winston/test/transports/file-maxfiles-test.js b/node_modules/winston/test/transports/file-maxfiles-test.js
new file mode 100644
index 0000000..62564a2
--- /dev/null
+++ b/node_modules/winston/test/transports/file-maxfiles-test.js
@@ -0,0 +1,102 @@
+/*
+ * file-maxfiles-test.js: Tests for instances of the File transport setting the max file size,
+ * and setting a number for max files created.
+ * maxSize * maxFiles = total storage used by winston.
+ *
+ * (C) 2011 Daniel Aristizabal
+ * MIT LICENSE
+ *
+ */
+
+var assert = require('assert'),
+ exec = require('child_process').exec,
+ fs = require('fs'),
+ path = require('path'),
+ vows = require('vows'),
+ winston = require('../../lib/winston'),
+ helpers = require('../helpers');
+
+var maxfilesTransport = new winston.transports.File({
+ timestamp: false,
+ json: false,
+ filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testmaxfiles.log'),
+ maxsize: 4096,
+ maxFiles: 3
+});
+
+vows.describe('winston/transports/file/maxfiles').addBatch({
+ "An instance of the File Transport": {
+ "when passed a valid filename": {
+ topic: maxfilesTransport,
+ "should be a valid transporter": function (transportTest) {
+ helpers.assertFile(transportTest);
+ },
+ "should set the maxFiles option correctly": function (transportTest) {
+ assert.isNumber(transportTest.maxFiles);
+ }
+ },
+ "when delete old test files": {
+ topic: function () {
+ exec('rm -rf ' + path.join(__dirname, '..', 'fixtures', 'logs', 'testmaxfiles*'), this.callback);
+ },
+ "and when passed more files than the maxFiles": {
+ topic: function () {
+ var that = this,
+ created = 0;
+
+ function data(ch) {
+ return new Array(1018).join(String.fromCharCode(65 + ch));
+ };
+
+ function logKbytes(kbytes, txt) {
+ //
+ // With no timestamp and at the info level,
+ // winston adds exactly 7 characters:
+ // [info](4)[ :](2)[\n](1)
+ //
+ for (var i = 0; i < kbytes; i++) {
+ maxfilesTransport.log('info', data(txt), null, function () { });
+ }
+ }
+
+ maxfilesTransport.on('logged', function () {
+ if (++created === 6) {
+ return that.callback();
+ }
+
+ logKbytes(4, created);
+ });
+
+ logKbytes(4, created);
+ },
+ "should be only 3 files called 5.log, 4.log and 3.log": function () {
+ for (var num = 0; num < 6; num++) {
+ var file = !num ? 'testmaxfiles.log' : 'testmaxfiles' + num + '.log',
+ fullpath = path.join(__dirname, '..', 'fixtures', 'logs', file);
+
+ // There should be no files with that name
+ if (num >= 0 && num < 3) {
+ assert.throws(function () {
+ fs.statSync(fullpath);
+ }, Error);
+ } else {
+ // The other files should be exist
+ assert.doesNotThrow(function () {
+ fs.statSync(fullpath);
+ }, Error);
+ }
+ }
+ },
+ "should have the correct content": function () {
+ ['D', 'E', 'F'].forEach(function (name, inx) {
+ var counter = inx + 3,
+ logsDir = path.join(__dirname, '..', 'fixtures', 'logs'),
+ content = fs.readFileSync(path.join(logsDir, 'testmaxfiles' + counter + '.log'), 'utf-8');
+ // The content minus the 7 characters added by winston
+ assert.lengthOf(content.match(new RegExp(name, 'g')), 4068);
+ });
+ }
+ }
+ }
+ }
+}).export(module);
diff --git a/node_modules/winston/test/transports/file-maxsize-test.js b/node_modules/winston/test/transports/file-maxsize-test.js
new file mode 100644
index 0000000..7d20e08
--- /dev/null
+++ b/node_modules/winston/test/transports/file-maxsize-test.js
@@ -0,0 +1,82 @@
+/*
+ * file-test.js: Tests for instances of the File transport
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENSE
+ *
+ */
+
+var assert = require('assert'),
+ exec = require('child_process').exec,
+ fs = require('fs'),
+ path = require('path'),
+ vows = require('vows'),
+ winston = require('../../lib/winston'),
+ helpers = require('../helpers');
+
+var maxsizeTransport = new winston.transports.File({
+ timestamp: false,
+ json: false,
+ filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testmaxsize.log'),
+ maxsize: 4096
+});
+
+vows.describe('winston/transports/file/maxsize').addBatch({
+ "An instance of the File Transport": {
+ "when passed a valid filename": {
+ "the log() method": {
+ topic: function () {
+ exec('rm -rf ' + path.join(__dirname, '..', 'fixtures', 'logs', 'testmaxsize*'), this.callback);
+ },
+ "when passed more than the maxsize": {
+ topic: function () {
+ var that = this,
+ data = new Array(1018).join('-');
+
+ //
+ // Setup a list of files which we will later stat.
+ //
+ that.files = [];
+
+ function logKbytes (kbytes) {
+ //
+ // With no timestamp and at the info level,
+ // winston adds exactly 7 characters:
+ // [info](4)[ :](2)[\n](1)
+ //
+ for (var i = 0; i < kbytes; i++) {
+ maxsizeTransport.log('info', data, null, function () { });
+ }
+ }
+
+ maxsizeTransport.on('open', function (file) {
+ var match = file.match(/(\d+)\.log$/),
+ count = match ? match[1] : 0;
+
+ that.files.push(file);
+
+ if (that.files.length === 5) {
+ return that.callback();
+ }
+
+ logKbytes(4);
+ });
+
+ logKbytes(4);
+ },
+ "should create multiple files correctly": function () {
+ this.files.forEach(function (file) {
+ try {
+ var stats = fs.statSync(file);
+ assert.equal(stats.size, 4096);
+ }
+ catch (ex) {
+ assert.isNull(ex);
+ }
+ });
+ }
+ }
+ }
+ }
+ }
+}).export(module); \ No newline at end of file
diff --git a/node_modules/winston/test/transports/file-open-test.js b/node_modules/winston/test/transports/file-open-test.js
new file mode 100644
index 0000000..15427a0
--- /dev/null
+++ b/node_modules/winston/test/transports/file-open-test.js
@@ -0,0 +1,57 @@
+/*
+ * file-open-test.js: Tests for File transport "open" event
+ *
+ * (C) 2014 William Wong
+ * MIT LICENSE
+ *
+ */
+
+var assert = require('assert'),
+ fs = require('fs'),
+ os = require('os'),
+ path = require('path'),
+ vows = require('vows'),
+ winston = require('../../lib/winston');
+
+vows.describe('winston/transports/file').addBatch({
+ 'An instance of the File Transport': {
+ topic: function () {
+ var callback = this.callback.bind(this),
+ logPath = path.resolve(__dirname, '../fixtures/logs/file-open-test.log');
+
+ try {
+ fs.unlinkSync(logPath);
+ } catch (ex) {
+ if (ex && ex.code !== 'ENOENT') { return callback(ex); }
+ }
+
+ var fileTransport = new (winston.transports.File)({
+ filename: logPath
+ }),
+ logger = new (winston.Logger)({
+ transports: [fileTransport]
+ }),
+ timeline = {};
+
+ fileTransport.open(function () {
+ timeline.open = Date.now();
+
+ setTimeout(function () {
+ logger.info('Hello, World!', function () {
+ timeline.logged = Date.now();
+ });
+ }, 100);
+
+ setTimeout(function () {
+ callback(null, timeline);
+ }, 1000);
+ });
+ },
+ 'should fire "open" event': function (results) {
+ assert.isTrue(!!results.open);
+ },
+ 'should fire "logged" event': function (results) {
+ assert.isTrue(!!results.logged);
+ }
+ }
+}).export(module); \ No newline at end of file
diff --git a/node_modules/winston/test/transports/file-stress-test.js b/node_modules/winston/test/transports/file-stress-test.js
new file mode 100644
index 0000000..8c4dcb9
--- /dev/null
+++ b/node_modules/winston/test/transports/file-stress-test.js
@@ -0,0 +1,72 @@
+/*
+ * file-stress-test.js: Tests for stressing File transport
+ *
+ * (C) 2014 William Wong
+ * MIT LICENSE
+ *
+ */
+
+var assert = require('assert'),
+ fs = require('fs'),
+ os = require('os'),
+ path = require('path'),
+ vows = require('vows'),
+ winston = require('../../lib/winston');
+
+vows.describe('winston/transports/file').addBatch({
+ 'A stressed instance of the File Transport': {
+ topic: function () {
+ var callback = this.callback.bind(this),
+ logPath = path.resolve(__dirname, '../fixtures/logs/file-stress-test.log');
+
+ try {
+ fs.unlinkSync(logPath);
+ } catch (ex) {
+ if (ex && ex.code !== 'ENOENT') { return callback(ex); }
+ }
+
+ var fileTransport = new (winston.transports.File)({
+ filename: logPath
+ }),
+ logger = new (winston.Logger)({
+ transports: [fileTransport]
+ });
+
+ fileTransport.on('open', function () {
+ setTimeout(function () {
+ clearInterval(interval);
+
+ logger.query({ order: 'asc' }, function (err, results) {
+ callback(null, results);
+ });
+ }, 100);
+ });
+
+ var logIndex = 0,
+ interval = setInterval(function () {
+ logger.info(++logIndex);
+ stress(200);
+ }, 0);
+
+ logger.info(++logIndex);
+ stress(200);
+
+ function stress(duration) {
+ var startTime = Date.now();
+
+ while (Date.now() - startTime < duration) {
+ Math.sqrt(Math.PI);
+ }
+ }
+ },
+ 'should not skip any log lines': function (results) {
+ var testIndex = 0;
+
+ results.file.forEach(function (log) {
+ if (+log.message !== ++testIndex) {
+ throw new Error('Number skipped');
+ }
+ });
+ }
+ }
+}).export(module);
diff --git a/node_modules/winston/test/transports/file-tailrolling-test.js b/node_modules/winston/test/transports/file-tailrolling-test.js
new file mode 100644
index 0000000..60a0674
--- /dev/null
+++ b/node_modules/winston/test/transports/file-tailrolling-test.js
@@ -0,0 +1,92 @@
+var assert = require('assert'),
+ fs = require('fs'),
+ path = require('path'),
+ vows = require('vows'),
+ winston = require('../../lib/winston'),
+ helpers = require('../helpers');
+
+var maxfilesTransport = new winston.transports.File({
+ timestamp: false,
+ json: false,
+ filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testtailrollingfiles.log'),
+ maxsize: 4096,
+ maxFiles: 3,
+ tailable: true
+});
+
+process.on('uncaughtException', function (err) {
+ console.log('caught exception');
+ console.error(err);
+});
+
+vows.describe('winston/transports/file/tailrolling').addBatch({
+ "An instance of the File Transport": {
+ "when delete old test files": {
+ topic: function () {
+ var logs = path.join(__dirname, '..', 'fixtures', 'logs');
+ fs.readdirSync(logs).forEach(function (file) {
+ if (~file.indexOf('testtailrollingfiles')) {
+ fs.unlinkSync(path.join(logs, file));
+ }
+ });
+
+ this.callback();
+ },
+ "and when passed more files than the maxFiles": {
+ topic: function () {
+ var that = this,
+ created = 0;
+
+ function data(ch) {
+ return new Array(1018).join(String.fromCharCode(65 + ch));
+ };
+
+ function logKbytes(kbytes, txt) {
+ //
+ // With no timestamp and at the info level,
+ // winston adds exactly 7 characters:
+ // [info](4)[ :](2)[\n](1)
+ //
+ for (var i = 0; i < kbytes; i++) {
+ maxfilesTransport.log('info', data(txt), null, function () { });
+ }
+ }
+
+ maxfilesTransport.on('logged', function () {
+ if (++created == 4) {
+ return that.callback();
+ }
+
+ logKbytes(4, created);
+ });
+
+ logKbytes(4, created);
+ },
+ "should be 3 log files, base to maxFiles - 1": function () {
+ var file, fullpath;
+ for (var num = 0; num < 4; num++) {
+ file = !num ? 'testtailrollingfiles.log' : 'testtailrollingfiles' + num + '.log';
+ fullpath = path.join(__dirname, '..', 'fixtures', 'logs', file);
+
+ if (num == 3) {
+ return assert.ok(!fs.existsSync(fullpath));
+ }
+
+ assert.ok(fs.existsSync(fullpath));
+ }
+
+ return false;
+ },
+ "should have files in correct order": function () {
+ var file, fullpath, content;
+ ['D', 'C', 'B'].forEach(function (letter, i) {
+ file = !i ? 'testtailrollingfiles.log' : 'testtailrollingfiles' + i + '.log';
+ content = fs.readFileSync(path.join(__dirname, '..', 'fixtures', 'logs', file), 'ascii');
+
+ assert.lengthOf(content.match(new RegExp(letter, 'g')), 4068);
+ });
+ }
+ }
+ }
+ }
+}).export(module); \ No newline at end of file
diff --git a/node_modules/winston/test/transports/file-test.js b/node_modules/winston/test/transports/file-test.js
new file mode 100644
index 0000000..e6f6b3a
--- /dev/null
+++ b/node_modules/winston/test/transports/file-test.js
@@ -0,0 +1,134 @@
+/*
+ * file-test.js: Tests for instances of the File transport
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENSE
+ *
+ */
+
+var path = require('path'),
+ vows = require('vows'),
+ fs = require('fs'),
+ assert = require('assert'),
+ winston = require('../../lib/winston'),
+ stdMocks = require('std-mocks'),
+ helpers = require('../helpers');
+
+var transport = require('./transport');
+
+var stream = fs.createWriteStream(
+ path.join(__dirname, '..', 'fixtures', 'logs', 'testfile.log')
+ ),
+ fileTransport = new (winston.transports.File)({
+ filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testfilename.log')
+ }),
+ failedFileTransport = new (winston.transports.File)({
+ filename: path.join(__dirname, '..', 'fixtures', 'logs', 'dir404', 'testfile.log')
+ }),
+ streamTransport = new (winston.transports.File)({ stream: stream });
+
+vows.describe('winston/transports/file').addBatch({
+ "An instance of the File Transport": {
+ "when passed a valid filename": {
+ "should have the proper methods defined": function () {
+ helpers.assertFile(fileTransport);
+ },
+ "the log() method": helpers.testNpmLevels(fileTransport, "should respond with true", function (ign, err, logged) {
+ assert.isNull(err);
+ assert.isTrue(logged);
+ })
+ },
+ "when passed an invalid filename": {
+ "should have proper methods defined": function () {
+ helpers.assertFile(failedFileTransport);
+ },
+ "should enter noop failed state": function () {
+ helpers.assertFailedTransport(failedFileTransport);
+ }
+ },
+ "when passed a valid file stream": {
+ "should have the proper methods defined": function () {
+ helpers.assertFile(streamTransport);
+ },
+ "the log() method": helpers.testNpmLevels(streamTransport, "should respond with true", function (ign, err, logged) {
+ assert.isNull(err);
+ assert.isTrue(logged);
+ })
+ },
+ "streaming to stdout": {
+ topic: function () {
+ var transport = new (winston.transports.File)({
+ stream: process.stdout, timestamp: false, json: false
+ });
+ stdMocks.use();
+ return transport;
+ },
+ "with showLevel off": {
+ topic: function (stdoutStreamTransport) {
+ stdoutStreamTransport.showLevel = false;
+ stdoutStreamTransport.log('info', '', undefined, this.callback);
+ },
+ "should not have level prepended": function () {
+ var output = stdMocks.flush(),
+ line = output.stdout[0];
+
+ assert.equal(line, '\n');
+ }
+ },
+ // there would be a "with showLevel on" here but I think it's a bug in
+ // this version of vows. ugprading causes even more problems
+ teardown: function() {
+ stdMocks.restore();
+ }
+ }
+ }
+}).addBatch({
+ "These tests have a non-deterministic end": {
+ topic: function () {
+ setTimeout(this.callback, 200);
+ },
+ "and this should be fixed before releasing": function () {
+ assert.isTrue(true);
+ }
+ }
+}).addBatch({
+ "Error object in metadata #610": {
+ topic: function () {
+ var myErr = new Error("foo");
+
+ fileTransport.log('info', 'test message', myErr, this.callback.bind(this, null, myErr));
+ },
+ "should not be modified": function (err, myErr) {
+ assert.equal(myErr.message, "foo");
+ // Not sure if this is the best possible way to check if additional props appeared
+ assert.deepEqual(Object.getOwnPropertyNames(myErr), Object.getOwnPropertyNames(new Error("foo")));
+ }
+ }
+}).addBatch({
+ "Date object in metadata": {
+ topic: function () {
+ var obj = new Date(1000);
+
+ fileTransport.log('info', 'test message', obj, this.callback.bind(this, null, obj));
+ },
+ "should not be modified": function (err, obj) {
+ // Not sure if this is the best possible way to check if additional props appeared
+ assert.deepEqual(Object.getOwnPropertyNames(obj), Object.getOwnPropertyNames(new Date()));
+ }
+ }
+}).addBatch({
+ "Plain object in metadata": {
+ topic: function () {
+ var obj = { message: "foo" };
+
+ fileTransport.log('info', 'test message', obj, this.callback.bind(this, null, obj));
+ },
+ "should not be modified": function (err, obj) {
+ assert.deepEqual(obj, { message: "foo" });
+ }
+ }
+}).addBatch({
+ "An instance of the File Transport": transport(winston.transports.File, {
+ filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testfile.log')
+ })
+}).export(module);
diff --git a/node_modules/winston/test/transports/http-test.js b/node_modules/winston/test/transports/http-test.js
new file mode 100644
index 0000000..65f3cc7
--- /dev/null
+++ b/node_modules/winston/test/transports/http-test.js
@@ -0,0 +1,70 @@
+/*
+ * http-test.js: Tests for instances of the HTTP transport
+ *
+ * MIT LICENSE
+ */
+
+var path = require('path'),
+ vows = require('vows'),
+ http = require('http'),
+ fs = require('fs'),
+ assert = require('assert'),
+ winston = require('../../lib/winston'),
+ helpers = require('../helpers'),
+ hock = require('hock');
+
+var transport = require('./transport');
+
+var host = '127.0.0.1';
+
+vows.describe('winston/transports/http').addBatch({
+ "When the HTTP endpoint": {
+ topic: function () {
+ var mock = this.mock = hock.createHock(),
+ self = this;
+
+ mock
+ .post('/log', {
+ "method":"collect",
+ "params":{
+ "level":"info",
+ "message":"hello",
+ "meta":{}
+ }
+ })
+ .min(1)
+ .max(1)
+ .reply(200);
+
+ var server = this.server = http.createServer(mock.handler);
+ server.listen(0, '0.0.0.0', this.callback);
+ },
+ "is running": function (err) {
+ assert.ifError(err);
+ },
+ "an instance of the Http transport": {
+ topic: function () {
+
+ var port = this.server.address().port;
+ var self = this,
+ httpTransport = new (winston.transports.Http)({
+ host: host,
+ port: port,
+ path: 'log'
+ });
+
+ httpTransport.log('info', 'hello', function (logErr, logged) {
+ self.mock.done(function (doneErr) {
+ self.callback(null, logErr, logged, doneErr);
+ });
+ });
+ },
+ "should log to the specified URL": function (_, err, logged, requested) {
+ assert.ifError(err);
+ assert.isTrue(logged);
+ assert.ifError(requested);
+ this.server.close();
+ }
+ }
+ }
+}).export(module);
diff --git a/node_modules/winston/test/transports/memory-test.js b/node_modules/winston/test/transports/memory-test.js
new file mode 100644
index 0000000..e8e1043
--- /dev/null
+++ b/node_modules/winston/test/transports/memory-test.js
@@ -0,0 +1,31 @@
+var path = require('path'),
+ vows = require('vows'),
+ assert = require('assert'),
+ winston = require('../../lib/winston'),
+ helpers = require('../helpers');
+
+var npmTransport = new (winston.transports.Memory)(),
+ syslogTransport = new (winston.transports.Memory)({ levels: winston.config.syslog.levels });
+
+vows.describe('winston/transports/memory').addBatch({
+ "An instance of the Memory Transport": {
+ "with npm levels": {
+ "should have the proper methods defined": function () {
+ helpers.assertMemory(npmTransport);
+ },
+ "the log() method": helpers.testNpmLevels(npmTransport, "should respond with true", function (ign, err, logged) {
+ assert.isNull(err);
+ assert.isTrue(logged);
+ })
+ },
+ "with syslog levels": {
+ "should have the proper methods defined": function () {
+ helpers.assertMemory(syslogTransport);
+ },
+ "the log() method": helpers.testSyslogLevels(syslogTransport, "should respond with true", function (ign, err, logged) {
+ assert.isNull(err);
+ assert.isTrue(logged);
+ })
+ }
+ }
+}).export(module); \ No newline at end of file
diff --git a/node_modules/winston/test/transports/transport.js b/node_modules/winston/test/transports/transport.js
new file mode 100644
index 0000000..0abf80a
--- /dev/null
+++ b/node_modules/winston/test/transports/transport.js
@@ -0,0 +1,212 @@
+var assert = require('assert'),
+ winston = require('../../lib/winston'),
+ helpers = require('../helpers');
+
+module.exports = function (transport, options) {
+ var logger = transport instanceof winston.Logger
+ ? transport
+ : new winston.Logger({
+ transports: [
+ new transport(options)
+ ]
+ });
+
+ // hack to fix transports that don't log
+ // any unit of time smaller than seconds
+ var common = require('../../lib/winston/common');
+ common.timestamp = function() {
+ return new Date().toISOString();
+ };
+
+ var transport = logger.transports[logger._names[0]];
+
+ var out = {
+ 'topic': logger,
+ 'when passed valid options': {
+ 'should have the proper methods defined': function () {
+ switch (transport.name) {
+ case 'console':
+ helpers.assertConsole(transport);
+ break;
+ case 'file':
+ helpers.assertFile(transport);
+ break;
+ case 'couchdb':
+ helpers.assertCouchdb(transport);
+ break;
+ }
+ assert.isFunction(transport.log);
+ }
+ },
+ 'the log() method': helpers.testNpmLevels(transport,
+ 'should respond with true', function (ign, err, logged) {
+ assert.isNull(err);
+ assert.isNotNull(logged);
+ }
+ ),
+ 'the stream() method': {
+ 'using no options': {
+ 'topic': function () {
+ if (!transport.stream) return;
+
+ logger.log('info', 'hello world', {});
+
+ var cb = this.callback,
+ j = 10,
+ i = 10,
+ results = [],
+ stream = logger.stream();
+
+ stream.on('log', function (log) {
+ results.push(log);
+ results.stream = stream;
+ if (!--j) cb(null, results);
+ });
+
+ stream.on('error', function (err) {
+ j = -1; //don't call the callback again
+ cb(err);
+ });
+
+ while (i--) logger.log('info', 'hello world ' + i, {});
+ },
+ 'should stream logs': function (err, results) {
+ if (!transport.stream) return;
+ assert.isNull(err);
+ results.forEach(function (log) {
+ assert.ok(log.message.indexOf('hello world') === 0
+ || log.message.indexOf('test message') === 0);
+ });
+ results.stream.destroy();
+ }
+ },
+ 'using the `start` option': {
+ 'topic': function () {
+ if (!transport.stream) return;
+
+ var cb = this.callback,
+ stream = logger.stream({ start: 0 });
+
+ stream.on('log', function (log) {
+ log.stream = stream;
+ if (cb) cb(null, log);
+ cb = null;
+ });
+ },
+ 'should stream logs': function (err, log) {
+ if (!transport.stream) return;
+ assert.isNull(err);
+ assert.isNotNull(log.message);
+ log.stream.destroy();
+ }
+ }
+ },
+ 'after the logs have flushed': {
+ topic: function () {
+ setTimeout(this.callback, 1000);
+ },
+ 'the query() method': {
+ 'using basic querying': {
+ 'topic': function () {
+ if (!transport.query) return;
+ var cb = this.callback;
+ logger.log('info', 'hello world', {}, function () {
+ logger.query(cb);
+ });
+ },
+ 'should return matching results': function (err, results) {
+ if (!transport.query) return;
+ assert.isNull(err);
+ results = results[transport.name];
+ while (!Array.isArray(results)) {
+ results = results[Object.keys(results).pop()];
+ }
+ var log = results.pop();
+ assert.ok(log.message.indexOf('hello world') === 0
+ || log.message.indexOf('test message') === 0);
+ }
+ },
+ 'using the `rows` option': {
+ 'topic': function () {
+ if (!transport.query) return;
+ var cb = this.callback;
+ logger.log('info', 'hello world', {}, function () {
+ logger.query({ rows: 1 }, cb);
+ });
+ },
+ 'should return one result': function (err, results) {
+ if (!transport.query) return;
+ assert.isNull(err);
+ results = results[transport.name];
+ while (!Array.isArray(results)) {
+ results = results[Object.keys(results).pop()];
+ }
+ assert.equal(results.length, 1);
+ }
+ },
+ 'using `fields` and `order` option': {
+ 'topic': function () {
+ if (!transport.query) return;
+ var cb = this.callback;
+ logger.log('info', 'hello world', {}, function () {
+ logger.query({ order: 'asc', fields: ['timestamp'] }, cb);
+ });
+ },
+ 'should return matching results': function (err, results) {
+ if (!transport.query) return;
+ assert.isNull(err);
+ results = results[transport.name];
+ while (!Array.isArray(results)) {
+ results = results[Object.keys(results).pop()];
+ }
+ assert.equal(Object.keys(results[0]).length, 1);
+ assert.ok(new Date(results.shift().timestamp)
+ < new Date(results.pop().timestamp));
+ }
+ },
+ 'using the `from` and `until` option': {
+ 'topic': function () {
+ if (!transport.query) return;
+ var cb = this.callback;
+ var start = Date.now() - (100 * 1000);
+ var end = Date.now() + (100 * 1000);
+ logger.query({ from: start, until: end }, cb);
+ },
+ 'should return matching results': function (err, results) {
+ if (!transport.query) return;
+ assert.isNull(err);
+ results = results[transport.name];
+ while (!Array.isArray(results)) {
+ results = results[Object.keys(results).pop()];
+ }
+ assert.ok(results.length >= 1);
+ }
+ },
+ 'using a bad `from` and `until` option': {
+ 'topic': function () {
+ if (!transport.query) return;
+ var cb = this.callback;
+ logger.log('info', 'bad from and until', {}, function () {
+ var now = Date.now() + 1000000;
+ logger.query({ from: now, until: now }, cb);
+ });
+ },
+ 'should return no results': function (err, results) {
+ if (!transport.query) return;
+ assert.isNull(err);
+ results = results[transport.name];
+ while (!Array.isArray(results)) {
+ results = results[Object.keys(results).pop()];
+ }
+ results = [results.filter(function(log) {
+ return log.message === 'bad from and until';
+ }).pop()];
+ assert.isUndefined(results[0]);
+ }
+ }
+ }
+ }
+ };
+
+ return out;
+};