1 // ========================================================================== 2 // Project: SproutCore - JavaScript Application Framework 3 // Copyright: ©2008-2011 Apple Inc. All rights reserved. 4 // License: Licensed under MIT license (see license.js) 5 // ========================================================================== 6 // ========================================================================== 7 // SC.Logger Unit Test 8 // ========================================================================== 9 10 /*globals module test equals */ 11 12 13 // Test console needed because testing for null functions, 14 // ie. setting the actual console.log = null means setting up 15 // and tearing down no longer work properly. 16 17 function testConsole() { 18 return { 19 log: function() { return true; }, 20 alert: function() { return true; }, 21 debug: function() { return true; }, 22 dir: function() { return true; }, 23 dirxml: function() { return true; }, 24 error: function() { return true; }, 25 group: function() { return true; }, 26 groupEnd: function() { return true; }, 27 info: function() { return true; }, 28 profile: function() { return true; }, 29 profileEnd: function() { return true; }, 30 time: function() { return true; }, 31 timeEnd: function() { return true; }, 32 trace: function() { return true; }, 33 warn: function() { return true; } 34 }; 35 } 36 37 module("SC.Logger", { 38 setup: function() { 39 SC.Logger.set('reporter', testConsole()); 40 41 SC.Logger.debugEnabled = true; 42 SC.Logger.format = true; 43 SC.Logger.fallBackOnLog = true; 44 SC.Logger.fallBackOnAlert = false; 45 }, 46 teardown: function() { 47 } 48 }); 49 50 51 // We'll use these a lot. 52 var debugMessage = "Test debug message", 53 infoMessage = "Test informational message", 54 warnMessage = "Test warning message", 55 errorMessage = "Test error message", 56 debugGroupTitle = "Test debug group title", 57 infoGroupTitle = "Test informational group title", 58 warnGroupTitle = "Test warning group title", 59 errorGroupTitle = "Test error group title"; 60 61 var outputAll = function() { 62 // Outputs a log message for each possible level. 63 SC.Logger.debugGroup(debugGroupTitle); 64 SC.Logger.debug(debugMessage); 65 SC.Logger.debugGroupEnd(); 66 67 SC.Logger.infoGroup(debugGroupTitle); 68 SC.Logger.info(infoMessage); 69 SC.Logger.infoGroupEnd(); 70 71 SC.Logger.warnGroup(debugGroupTitle); 72 SC.Logger.warn(warnMessage); 73 SC.Logger.warnGroupEnd(); 74 75 SC.Logger.errorGroup(debugGroupTitle); 76 SC.Logger.error(errorMessage); 77 SC.Logger.errorGroupEnd(); 78 }; 79 80 81 82 test("exists", function() { 83 equals(SC.Logger.get('exists'), true, "Reporter does exist check"); 84 85 SC.Logger.set('reporter', null); 86 equals(SC.Logger.get('exists'), false, "Reporter does not exist check"); 87 }); 88 89 test("profile", function() { 90 equals(SC.Logger.profile(), true, "profile() function is defined"); 91 92 SC.Logger.get('reporter').profile = null; 93 equals(SC.Logger.profile(), false, "profile() function is null"); 94 }); 95 96 test("profileEnd", function() { 97 equals(SC.Logger.profileEnd(), true, "profileEnd() function is defined"); 98 99 SC.Logger.get('reporter').profileEnd = null; 100 equals(SC.Logger.profileEnd(), false, "profileEnd() function is null"); 101 }); 102 103 test("time", function() { 104 equals(SC.Logger.time('mytime'), true, "time() function is defined"); 105 106 SC.Logger.get('reporter').time = null; 107 equals(SC.Logger.time('mytime'), false, "time() function is null"); 108 }); 109 110 test("timeEnd", function() { 111 equals(SC.Logger.timeEnd('mytime'), true, "timeEnd() function is defined"); 112 113 SC.Logger.get('reporter').timeEnd = null; 114 equals(SC.Logger.timeEnd('mytime'), false, "timeEnd() function is null"); 115 }); 116 117 test("trace", function() { 118 equals(SC.Logger.trace(), true, "trace() function is defined"); 119 120 SC.Logger.get('reporter').trace = null; 121 equals(SC.Logger.trace(), false, "trace() function is null"); 122 }); 123 124 test("_argumentsToString", function() { 125 equals(SC.Logger._argumentsToString.apply(SC.Logger, ["test", "test2"]), "test" + SC.LOGGER_LOG_DELIMITER + "test2", "Formatting using default delimiter"); 126 127 SC.LOGGER_LOG_DELIMITER = "|"; 128 equals(SC.Logger._argumentsToString.apply(SC.Logger, ["test", "test2"]), "test|test2", "Formatting using custom delimiter"); 129 }); 130 131 132 // .......................................................... 133 // LOG LEVELS 134 // 135 // Since we can't really test whether or not things are output to the console, 136 // we'll do all of our log level testing based on the log recording mechanism. 137 // 138 // In case anybody else has recorded a log message, all of these tests will 139 // start out by clearing the recorded log messages array. 140 141 test("Ensure that log levels function properly: none", function() { 142 SC.Logger.set('recordedLogMessages', null); 143 144 SC.Logger.set('logRecordingLevel', SC.LOGGER_LEVEL_NONE); 145 outputAll(); 146 147 // If it was null before, it should be still be null, since no messages 148 // should have been logged. 149 equals(SC.Logger.get('recordedLogMessages'), null, "recordedLogMessages remains null"); 150 151 // If it was an empty array before, it should still be an empty array. 152 SC.Logger.set('recordedLogMessages', []); 153 outputAll(); 154 equals(SC.Logger.getPath('recordedLogMessages.length'), 0, "recordedLogMessages remains an empty array"); 155 }); 156 157 test("Ensure that log levels function properly: debug", function() { 158 SC.Logger.set('recordedLogMessages', null); 159 160 SC.Logger.set('logRecordingLevel', SC.LOGGER_LEVEL_DEBUG); 161 outputAll(); 162 163 // All four messages (plus group begin / end directives) should have been 164 // logged. 165 equals(SC.Logger.getPath('recordedLogMessages.length'), 12, "recordedLogMessages should have all twelve entries"); 166 167 equals(SC.Logger.getPath('recordedLogMessages.1').message, debugMessage, "recordedLogMessages[1] should be the debug message"); 168 equals(SC.Logger.getPath('recordedLogMessages.4').message, infoMessage, "recordedLogMessages[4] should be the info message"); 169 equals(SC.Logger.getPath('recordedLogMessages.7').message, warnMessage, "recordedLogMessages[7] should be the warn message"); 170 equals(SC.Logger.getPath('recordedLogMessages.10').message, errorMessage, "recordedLogMessages[10] should be the error message"); 171 }); 172 173 test("Ensure that log levels function properly: info", function() { 174 SC.Logger.set('recordedLogMessages', null); 175 176 SC.Logger.set('logRecordingLevel', SC.LOGGER_LEVEL_INFO); 177 outputAll(); 178 179 // Three messages (plus group begin / end directives) should have been 180 // logged. 181 equals(SC.Logger.getPath('recordedLogMessages.length'), 9, "recordedLogMessages should have nine entries"); 182 183 equals(SC.Logger.getPath('recordedLogMessages.1').message, infoMessage, "recordedLogMessages[1] should be the info message"); 184 equals(SC.Logger.getPath('recordedLogMessages.4').message, warnMessage, "recordedLogMessages[4] should be the warn message"); 185 equals(SC.Logger.getPath('recordedLogMessages.7').message, errorMessage, "recordedLogMessages[7] should be the error message"); 186 }); 187 188 test("Ensure that log levels function properly: warn", function() { 189 SC.Logger.set('recordedLogMessages', null); 190 191 SC.Logger.set('logRecordingLevel', SC.LOGGER_LEVEL_WARN); 192 outputAll(); 193 194 // Two messages (plus group begin / end directives) should have been logged. 195 equals(SC.Logger.getPath('recordedLogMessages.length'), 6, "recordedLogMessages should have 6 entries"); 196 197 equals(SC.Logger.getPath('recordedLogMessages.1').message, warnMessage, "recordedLogMessages[1] should be the warn message"); 198 equals(SC.Logger.getPath('recordedLogMessages.4').message, errorMessage, "recordedLogMessages[4] should be the error message"); 199 }); 200 201 test("Ensure that log levels function properly: error", function() { 202 SC.Logger.set('recordedLogMessages', null); 203 204 SC.Logger.set('logRecordingLevel', SC.LOGGER_LEVEL_ERROR); 205 outputAll(); 206 207 // Only the error message (plus group begin / end directives) should have 208 // been logged. 209 equals(SC.Logger.getPath('recordedLogMessages.length'), 3, "recordedLogMessages should have three entries"); 210 211 // That message should be equal to the error message. 212 equals(SC.Logger.getPath('recordedLogMessages.1').message, errorMessage, "recordedLogMessages[1] should be the error message"); 213 }); 214 215 216 test("Ensure that log messages via the “will format” methods actually format", function() { 217 SC.Logger.set('recordedLogMessages', null); 218 SC.Logger.set('logRecordingLevel', SC.LOGGER_LEVEL_DEBUG); 219 220 var format = "This message should be formatted: %@:%@", 221 expected = format.fmt(null, 1); 222 223 SC.Logger.debug(format, null, 1); 224 SC.Logger.info(format, null, 1); 225 SC.Logger.warn(format, null, 1); 226 SC.Logger.error(format, null, 1); 227 228 equals(SC.Logger.getPath('recordedLogMessages.0').message, expected, "debug() should call String.fmt"); 229 equals(SC.Logger.getPath('recordedLogMessages.1').message, expected, "info() should call String.fmt"); 230 equals(SC.Logger.getPath('recordedLogMessages.2').message, expected, "warn() should call String.fmt"); 231 equals(SC.Logger.getPath('recordedLogMessages.3').message, expected, "error() should call String.fmt"); 232 }); 233 234 test("Ensure that log messages via the “will not format” methods don’t format, but are still recorded", function() { 235 SC.Logger.set('recordedLogMessages', null); 236 SC.Logger.set('logRecordingLevel', SC.LOGGER_LEVEL_DEBUG); 237 238 var message = "This message should not be formatted: %@:%@"; 239 SC.Logger.debugWithoutFmt(message, null, 1); 240 SC.Logger.infoWithoutFmt(message, null, 1); 241 SC.Logger.warnWithoutFmt(message, null, 1); 242 SC.Logger.errorWithoutFmt(message, null, 1); 243 244 // They should still be recorded and identified as a message. 245 equals(SC.Logger.getPath('recordedLogMessages.0').message, true, "debugWithoutFmt() should still record"); 246 equals(SC.Logger.getPath('recordedLogMessages.1').message, true, "infoWithoutFmt() should still record"); 247 equals(SC.Logger.getPath('recordedLogMessages.2').message, true, "warnWithoutFmt() should still record"); 248 equals(SC.Logger.getPath('recordedLogMessages.3').message, true, "errorWithoutFmt() should still record"); 249 250 equals(SC.Logger.getPath('recordedLogMessages.0').originalArguments[0], message, "debugWithoutFmt() should not call String.fmt"); 251 equals(SC.Logger.getPath('recordedLogMessages.0').originalArguments[1], null, "debugWithoutFmt() should record all the arguments (1)"); 252 equals(SC.Logger.getPath('recordedLogMessages.0').originalArguments[2], 1, "debugWithoutFmt() should record all the arguments (2)"); 253 254 equals(SC.Logger.getPath('recordedLogMessages.1').originalArguments[0], message, "infoWithoutFmt() should not call String.fmt"); 255 equals(SC.Logger.getPath('recordedLogMessages.1').originalArguments[1], null, "infoWithoutFmt() should record all the arguments (1)"); 256 equals(SC.Logger.getPath('recordedLogMessages.2').originalArguments[2], 1, "infoWithoutFmt() should record all the arguments (2)"); 257 258 equals(SC.Logger.getPath('recordedLogMessages.2').originalArguments[0], message, "warnWithoutFmt() should not call String.fmt"); 259 equals(SC.Logger.getPath('recordedLogMessages.2').originalArguments[1], null, "warnWithoutFmt() should record all the arguments (1)"); 260 equals(SC.Logger.getPath('recordedLogMessages.2').originalArguments[2], 1, "warnWithoutFmt() should record all the arguments (2)"); 261 262 equals(SC.Logger.getPath('recordedLogMessages.3').originalArguments[0], message, "errorWithoutFmt() should not call String.fmt"); 263 equals(SC.Logger.getPath('recordedLogMessages.3').originalArguments[1], null, "errorWithoutFmt() should record all the arguments (1)"); 264 equals(SC.Logger.getPath('recordedLogMessages.3').originalArguments[2], 1, "errorWithoutFmt() should record all the arguments (2)"); 265 }); 266 267 268 269 // .......................................................... 270 // LOG MESSAGE PREFIX 271 // 272 test("Ensure that the log message prefix is respected", function() { 273 SC.Logger.set('recordedLogMessages', null); 274 275 SC.Logger.set('logRecordingLevel', SC.LOGGER_LEVEL_DEBUG); 276 277 SC.Logger.set('messagePrefix', "prefix: "); 278 SC.Logger.debug("message"); 279 280 equals(SC.Logger.getPath('recordedLogMessages.0').message, "prefix: message", "The message should have the specified prefix"); 281 }); 282