diff --git a/test/test-configureNoLevels.js b/test/test-configureNoLevels.js new file mode 100644 index 0000000..c2de2f6 --- /dev/null +++ b/test/test-configureNoLevels.js @@ -0,0 +1,126 @@ +// This test shows unexpected behaviour for log4js.configure() in log4js-node@0.4.3 and earlier: +// 1) log4js.configure(), log4js.configure(null), log4js.configure({}), log4js.configure() +// all set all loggers levels to trace, even if they were previously set to something else. +// 2) log4js.configure({levels:{}}), log4js.configure({levels: {foo: bar}}) leaves previously set logger levels intact. +// + +// Basic set up +var vows = require('vows'); +var assert = require('assert'); +var toLevel = require('../lib/levels').toLevel; + +// uncomment one or other of the following to see progress (or not) while running the tests +// var showProgress = console.log; +var showProgress = function() {}; + + +// Define the array of levels as string to iterate over. +var strLevels= ['Trace','Debug','Info','Warn','Error','Fatal']; + +// setup the configurations we want to test +var configs = { + 'nop': 'nop', // special case where the iterating vows generator will not call log4js.configure + 'is undefined': undefined, + 'is null': null, + 'is empty': {}, + 'has no levels': {foo: 'bar'}, + 'has null levels': {levels: null}, + 'has empty levels': {levels: {}}, + 'has random levels': {levels: {foo: 'bar'}}, + 'has some valid levels': {levels: {A: 'INFO'}} +} + +// Set up the basic vows batches for this test +var batches = []; + + +function getLoggerName(level) { + return level+'-logger'; +} + +// the common vows top-level context, whether log4js.configure is called or not +// just making sure that the code is common, +// so that there are no spurious errors in the tests themselves. +function getTopLevelContext(nop, configToTest, name) { + return { + topic: function() { + var log4js = require('../lib/log4js'); + // create loggers for each level, + // keeping the level in the logger's name for traceability + strLevels.forEach(function(l) { + log4js.getLogger(getLoggerName(l)).setLevel(l); + }); + + if (!nop) { + showProgress('** Configuring log4js with', configToTest); + log4js.configure(configToTest); + } + else { + showProgress('** Not configuring log4js'); + } + return log4js; + } + } +}; + +showProgress('Populating batch object...'); + +// Populating the batches programmatically, +// as there are (configs.length x strLevels.length x strLevels.length) = 324 possible test combinations +for (var cfg in configs) { + var configToTest = configs[cfg]; + var nop = configToTest === 'nop'; + var context; + if (nop) { + context = 'Setting up loggers with initial levels, then NOT setting a configuration,'; + } + else { + context = 'Setting up loggers with initial levels, then setting a configuration which '+cfg+','; + } + + showProgress('Setting up the vows batch and context for '+context); + // each config to be tested has its own vows batch with a single top-level context + var batch={}; + batch[context]= getTopLevelContext(nop, configToTest, context); + batches.push(batch); + + // each top-level context has strLevels sub-contexts, one per logger which has set to a specific level in the top-level context's topic + strLevels.forEach(function (baseLevel) { + var baseLevelSubContext = 'and checking the logger whose level was set to '+baseLevel ; + batch[context][baseLevelSubContext] = {topic: baseLevel}; + + // each logging level has strLevels sub-contexts, + // to exhaustively test all the combinations of setLevel(baseLevel) and isLevelEnabled(comparisonLevel) per config + strLevels.forEach(function (comparisonLevel) { + var comparisonLevelSubContext = 'with isLevelEnabled('+comparisonLevel+')'; + + // calculate this independently of log4js, but we'll add a vow later on to check that we're not mismatched with log4js + var expectedResult = strLevels.indexOf(baseLevel) <= strLevels.indexOf(comparisonLevel); + + // the topic simply gathers all the parameters for the vow into an object, to simplify the vow's work. + batch[context][baseLevelSubContext][comparisonLevelSubContext] = {topic: function(baseLevel, log4js){ + return {comparisonLevel: comparisonLevel, baseLevel: baseLevel, log4js: log4js, expectedResult: expectedResult}; + }}; + + var vow = 'should return '+expectedResult; + batch[context][baseLevelSubContext][comparisonLevelSubContext][vow] = function(topic){ + var result = topic.log4js.getLogger(getLoggerName(topic.baseLevel)).isLevelEnabled(topic.log4js.levels.toLevel(topic.comparisonLevel)); + assert.equal(result, topic.expectedResult, 'Failed: '+getLoggerName(topic.baseLevel)+'.isLevelEnabled( '+topic.comparisonLevel+' ) returned '+result); + }; + + // the extra vow to check the comparison between baseLevel and comparisonLevel we performed earlier matches log4js' comparison too + batch[context][baseLevelSubContext][comparisonLevelSubContext]['finally checking for comparison mismatch with log4js'] = function(topic){ + var er = topic.log4js.levels.toLevel(topic.baseLevel).isLessThanOrEqualTo(topic.log4js.levels.toLevel(topic.comparisonLevel)); + assert.equal(er, topic.expectedResult, 'Mismatch: for setLevel('+topic.baseLevel+') was expecting a comparison with '+topic.comparisonLevel+' to be '+topic.expectedResult); + }; + }); + }); +}; + +showProgress('Running tests'); +var v = vows.describe('log4js.configure(), with or without a "levels" property'); + +batches.forEach(function(batch) {v=v.addBatch(batch)}); + +v.export(module); +