helpers.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /*
  2. * helpers.js: Test helpers for winston
  3. *
  4. * (C) 2010 Charlie Robbins
  5. * MIT LICENSE
  6. *
  7. */
  8. var assert = require('assert'),
  9. fs = require('fs'),
  10. path = require('path'),
  11. spawn = require('child_process').spawn,
  12. util = require('util'),
  13. vows = require('vows'),
  14. winston = require('../lib/winston');
  15. var helpers = exports;
  16. helpers.size = function (obj) {
  17. var size = 0, key;
  18. for (key in obj) {
  19. if (obj.hasOwnProperty(key)) {
  20. size++;
  21. }
  22. }
  23. return size;
  24. };
  25. helpers.tryUnlink = function (file) {
  26. try { fs.unlinkSync(file) }
  27. catch (ex) { }
  28. };
  29. helpers.assertDateInfo = function (info) {
  30. assert.isNumber(Date.parse(info));
  31. };
  32. helpers.assertProcessInfo = function (info) {
  33. assert.isNumber(info.pid);
  34. assert.isNumber(info.uid);
  35. assert.isNumber(info.gid);
  36. assert.isString(info.cwd);
  37. assert.isString(info.execPath);
  38. assert.isString(info.version);
  39. assert.isArray(info.argv);
  40. assert.isObject(info.memoryUsage);
  41. };
  42. helpers.assertOsInfo = function (info) {
  43. assert.isArray(info.loadavg);
  44. assert.isNumber(info.uptime);
  45. };
  46. helpers.assertTrace = function (trace) {
  47. trace.forEach(function (site) {
  48. assert.isTrue(!site.column || typeof site.column === 'number');
  49. assert.isTrue(!site.line || typeof site.line === 'number');
  50. assert.isTrue(!site.file || typeof site.file === 'string');
  51. assert.isTrue(!site.method || typeof site.method === 'string');
  52. assert.isTrue(!site.function || typeof site.function === 'string');
  53. assert.isTrue(typeof site.native === 'boolean');
  54. });
  55. };
  56. helpers.assertLogger = function (logger, level) {
  57. assert.instanceOf(logger, winston.Logger);
  58. assert.isFunction(logger.log);
  59. assert.isFunction(logger.add);
  60. assert.isFunction(logger.remove);
  61. assert.equal(logger.level, level || "info");
  62. Object.keys(logger.levels).forEach(function (method) {
  63. assert.isFunction(logger[method]);
  64. });
  65. };
  66. helpers.assertConsole = function (transport) {
  67. assert.instanceOf(transport, winston.transports.Console);
  68. assert.isFunction(transport.log);
  69. };
  70. helpers.assertMemory = function (transport) {
  71. assert.instanceOf(transport, winston.transports.Memory);
  72. assert.isFunction(transport.log);
  73. };
  74. helpers.assertFile = function (transport) {
  75. assert.instanceOf(transport, winston.transports.File);
  76. assert.isFunction(transport.log);
  77. };
  78. helpers.assertCouchdb = function (transport) {
  79. assert.instanceOf(transport, winston.transports.Couchdb);
  80. assert.isFunction(transport.log);
  81. };
  82. helpers.assertHandleExceptions = function (options) {
  83. return {
  84. topic: function () {
  85. var that = this,
  86. child = spawn('node', [options.script]);
  87. helpers.tryUnlink(options.logfile);
  88. child.on('exit', function () {
  89. fs.readFile(options.logfile, that.callback);
  90. });
  91. },
  92. "should save the error information to the specified file": function (err, data) {
  93. assert.isTrue(!err);
  94. data = JSON.parse(data);
  95. assert.isObject(data);
  96. helpers.assertProcessInfo(data.process);
  97. helpers.assertOsInfo(data.os);
  98. helpers.assertTrace(data.trace);
  99. if (options.message) {
  100. assert.equal('uncaughtException: ' + options.message, data.message);
  101. }
  102. }
  103. };
  104. };
  105. helpers.assertFailedTransport = function (transport) {
  106. return {
  107. topic: function () {
  108. var self = this;
  109. transport.on('error', function(emitErr){
  110. transport.log('error', 'test message 2', {}, function(logErr, logged){
  111. self.callback(emitErr, logErr);
  112. });
  113. });
  114. transport.log('error', 'test message');
  115. },
  116. "should emit an error": function (emitErr, logErr) {
  117. assert.instanceOf(emitErr, Error);
  118. assert.equal(emitErr.code, 'ENOENT');
  119. },
  120. "should enter noop failed state": function (emitErr, logErr) {
  121. assert.instanceOf(logErr, Error);
  122. assert.equal(transport._failures, transport.maxRetries);
  123. }
  124. };
  125. };
  126. helpers.testNpmLevels = function (transport, assertMsg, assertFn) {
  127. return helpers.testLevels(winston.config.npm.levels, transport, assertMsg, assertFn);
  128. };
  129. helpers.testSyslogLevels = function (transport, assertMsg, assertFn) {
  130. return helpers.testLevels(winston.config.syslog.levels, transport, assertMsg, assertFn);
  131. };
  132. helpers.testLevels = function (levels, transport, assertMsg, assertFn) {
  133. var tests = {};
  134. Object.keys(levels).forEach(function (level) {
  135. var test = {
  136. topic: function () {
  137. transport.log(level, 'test message', {}, this.callback.bind(this, null));
  138. }
  139. };
  140. test[assertMsg] = assertFn;
  141. tests['with the ' + level + ' level'] = test;
  142. });
  143. var metadatatest = {
  144. topic: function () {
  145. transport.log('info', 'test message', { metadata: true }, this.callback.bind(this, null));
  146. }
  147. };
  148. metadatatest[assertMsg] = assertFn;
  149. tests['when passed metadata'] = metadatatest;
  150. var primmetadatatest = {
  151. topic: function () {
  152. transport.log('info', 'test message', 'metadata', this.callback.bind(this, null));
  153. }
  154. };
  155. primmetadatatest[assertMsg] = assertFn;
  156. tests['when passed primitive metadata'] = primmetadatatest;
  157. var circmetadata = { };
  158. circmetadata['metadata'] = circmetadata;
  159. var circmetadatatest = {
  160. topic: function () {
  161. transport.log('info', 'test message', circmetadata, this.callback.bind(this, null));
  162. }
  163. };
  164. circmetadatatest[assertMsg] = assertFn;
  165. tests['when passed circular metadata'] = circmetadatatest;
  166. return tests;
  167. };
  168. helpers.assertOptionsThrow = function (options, errMsg) {
  169. return function () {
  170. assert.throws(
  171. function () {
  172. try {
  173. new (winston.transports.Console)(options);
  174. } catch (err) {
  175. throw(err);
  176. }
  177. },
  178. new RegExp('^' + errMsg.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + '$')
  179. );
  180. }
  181. };
  182. helpers.assertStderrLevels = function (transport, stderrLevels) {
  183. return function () {
  184. assert.equal(
  185. JSON.stringify(Object.keys(transport.stderrLevels).sort()),
  186. JSON.stringify(stderrLevels.sort())
  187. );
  188. }
  189. };
  190. helpers.testLoggingToStreams = function (levels, transport, stderrLevels, stdMocks) {
  191. return {
  192. topic: function () {
  193. stdMocks.use();
  194. transport.showLevel = true;
  195. Object.keys(levels).forEach(function (level) {
  196. transport.log(
  197. level,
  198. level + ' should go to ' + (stderrLevels.indexOf(level) > -1 ? 'stderr' : 'stdout'),
  199. {},
  200. function () {}
  201. );
  202. });
  203. var output = stdMocks.flush();
  204. stdMocks.restore();
  205. this.callback(null, output, levels);
  206. },
  207. "output should go to the appropriate streams": function (ign, output, levels) {
  208. var outCount = 0,
  209. errCount = 0;
  210. Object.keys(levels).forEach(function (level) {
  211. var line;
  212. if (stderrLevels.indexOf(level) > -1) {
  213. line = output.stderr[errCount++];
  214. assert.equal(line, level + ': ' + level + ' should go to stderr\n');
  215. } else {
  216. line = output.stdout[outCount++];
  217. assert.equal(line, level + ': ' + level + ' should go to stdout\n');
  218. }
  219. });
  220. }
  221. }
  222. };