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