blob: 55bd2ca955e0468261d8e9f63a1ca776f9b038c2 [file] [log] [blame]
Siobhan Tullye18b3442014-02-23 14:23:34 -05001/**
2 * Copyright 2013 Tim Down.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17function array_contains(arr, val) {
18 for (var i = 0; i < arr.length; i++) {
19 if (arr[i] == val) {
20 return true;
21 }
22 }
23 return false;
24}
25
26// Recursively checks that obj2's interface contains all of obj1's
27// interface (functions and objects only)
28function compareObjectInterface(obj1, obj1_name, obj2, obj2_name, namePrefix) {
29 if (!namePrefix) {
30 namePrefix = "";
31 }
32 var obj1PropertyNames = new Array();
33 for (var i in obj1) {
34 if (i != "prototype" && i != "arguments") {
35 obj1PropertyNames.push(i);
36 }
37 }
38 if (obj1 && obj1.prototype && !array_contains(obj1PropertyNames, "prototype")) {
39 //obj1PropertyNames.push("prototype");
40 }
41 for (var j = 0; j < obj1PropertyNames.length; j++) {
42 var propertyName = obj1PropertyNames[j];
43 if ((typeof obj1[propertyName] == "function" || typeof obj1[propertyName] == "object") && !(obj1[propertyName] instanceof Array)) {
44 var propertyFullyQualifiedName = (namePrefix == "") ? propertyName : namePrefix + "." + propertyName;
45 try {
46 if (typeof obj2[propertyName] == "undefined") {
47 throw new Error(obj2_name + " does not contain " + propertyFullyQualifiedName + " in " + obj1_name);
48 } else if (typeof obj2[propertyName] != typeof obj1[propertyName]){
49 throw new Error(obj2_name + "'s " + propertyFullyQualifiedName + " is of the wrong type: " + typeof obj2[propertyName] + " when it is type " + typeof obj1[propertyName] + " in " + obj1_name);
50 } else if (obj1[propertyName] != Function.prototype.apply) {
51 if (!compareObjectInterface(obj1[propertyName], obj1_name, obj2[propertyName], obj2_name, propertyFullyQualifiedName)) {
52 throw new Error("Interfaces don't match");
53 }
54 }
55 } catch(ex) {
56 throw new Error("Exception while checking property name " + propertyFullyQualifiedName + " in " + obj2_name + ": " + ex.message);
57 }
58 }
59 }
60 return true;
61};
62
63// Simply tests a layout for exceptions when formatting
64var testLayoutWithVariables = function(layout, t) {
65 var emptyObject = {};
66 var emptyArray = [];
67 var emptyString = "";
68 var localUndefined = emptyArray[0];
69 var oneLevelObject = {
70 "name": "One-level object"
71 };
72 var twoLevelObject = {
73 "name": "Two-level object",
74 "data": oneLevelObject
75 };
76 var threeLevelObject = {
77 "name": "Three-level object",
78 "data": twoLevelObject
79 };
80 var anArray = [
81 3,
82 "stuff",
83 true,
84 false,
85 0,
86 null,
87 localUndefined,
88 3.14,
89 function(p) { return "I'm a function"; },
90 [1, "things"]
91 ];
92 var arrayOfTestItems = [emptyObject, emptyString, emptyString, localUndefined, oneLevelObject,
93 twoLevelObject, threeLevelObject, anArray];
94
95 t.log("Testing layout " + layout)
96 for (var i = 0; i < arrayOfTestItems.length; i++) {
97 var ex = new Error("Test error");
98 var loggingEvent = new log4javascript.LoggingEvent(t.logger, new Date(), log4javascript.Level.INFO,
99 [arrayOfTestItems[i]], null);
100 t.log("Formatting", arrayOfTestItems[i], result);
101 var result = layout.format(loggingEvent);
102 // Now try with an exception
103 loggingEvent.exception = ex;
104 t.log("Formatting with exception", arrayOfTestItems[i], result);
105 result = layout.format(loggingEvent);
106 }
107};
108
109xn.test.enableTestDebug = true;
110xn.test.enable_log4javascript = false;
111
112xn.test.suite("log4javascript tests", function(s) {
113 log4javascript.logLog.setQuietMode(true);
114 var ArrayAppender = function(layout) {
115 if (layout) {
116 this.setLayout(layout);
117 }
118 this.logMessages = [];
119 };
120
121 ArrayAppender.prototype = new log4javascript.Appender();
122
123 ArrayAppender.prototype.layout = new log4javascript.NullLayout();
124
125 ArrayAppender.prototype.append = function(loggingEvent) {
126 var formattedMessage = this.getLayout().format(loggingEvent);
127 if (this.getLayout().ignoresThrowable()) {
128 formattedMessage += loggingEvent.getThrowableStrRep();
129 }
130 this.logMessages.push(formattedMessage);
131 };
132
133 ArrayAppender.prototype.toString = function() {
134 return "[ArrayAppender]";
135 };
136
137 s.setUp = function(t) {
138 t.logger = log4javascript.getLogger("test");
139 t.logger.removeAllAppenders();
140 t.appender = new ArrayAppender();
141 t.logger.addAppender(t.appender);
142 };
143
144 s.tearDown = function(t) {
145 t.logger.removeAppender(t.appender);
146 log4javascript.resetConfiguration();
147 };
148
149 s.test("Stub script interface test", function(t) {
150 try {
151 compareObjectInterface(log4javascript, "log4javascript", log4javascript_stub, "log4javascript_stub");
152 } catch (ex) {
153 t.fail(ex);
154 }
155 });
156
157 s.test("Disable log4javascript test", function(t) {
158 log4javascript.setEnabled(false);
159 t.logger.debug("TEST");
160 t.assertEquals(t.appender.logMessages.length, 0);
161 log4javascript.setEnabled(true);
162 });
163
164 s.test("Array.splice test 1", function(t) {
165 var a = ["Marlon", "Ashley", "Darius", "Lloyd"];
166 var deletedItems = a.splice(1, 2);
167 t.assertEquals(a.join(","), "Marlon,Lloyd");
168 t.assertEquals(deletedItems.join(","), "Ashley,Darius");
169 });
170
171 s.test("Array.splice test 2", function(t) {
172 var a = ["Marlon", "Ashley", "Darius", "Lloyd"];
173 var deletedItems = a.splice(1, 1, "Malky", "Jay");
174 t.assertEquals(a.join(","), "Marlon,Malky,Jay,Darius,Lloyd");
175 t.assertEquals(deletedItems.join(","), "Ashley");
176 });
177
178 s.test("array_remove test", function(t) {
179 var array_remove = log4javascript.evalInScope("array_remove");
180 var a = ["Marlon", "Ashley", "Darius"];
181 array_remove(a, "Darius");
182 t.assertEquals(a.join(","), "Marlon,Ashley");
183 });
184
185 s.test("array_remove with empty array test", function(t) {
186 var array_remove = log4javascript.evalInScope("array_remove");
187 var a = [];
188 array_remove(a, "Darius");
189 t.assertEquals(a.join(","), "");
190 });
191
192 s.test("Logger logging test", function(t) {
193 // Should log since the default level for loggers is DEBUG and
194 // the default threshold for appenders is ALL
195 t.logger.debug("TEST");
196 t.assertEquals(t.appender.logMessages.length, 1);
197 });
198
199 s.test("Logger levels test", function(t) {
200 var originalLevel = t.logger.getEffectiveLevel();
201 t.logger.setLevel(log4javascript.Level.INFO);
202 t.logger.debug("TEST");
203 t.logger.setLevel(originalLevel);
204 t.assertEquals(t.appender.logMessages.length, 0);
205 });
206
207 s.test("Logger getEffectiveLevel inheritance test 1", function(t) {
208 var parentLogger = log4javascript.getLogger("test1");
209 var childLogger = log4javascript.getLogger("test1.test2");
210 parentLogger.setLevel(log4javascript.Level.ERROR);
211 t.assertEquals(childLogger.getEffectiveLevel(), log4javascript.Level.ERROR);
212 });
213
214 s.test("Logger getEffectiveLevel inheritance test 2", function(t) {
215 var grandParentLogger = log4javascript.getLogger("test1");
216 var childLogger = log4javascript.getLogger("test1.test2.test3");
217 grandParentLogger.setLevel(log4javascript.Level.ERROR);
218 t.assertEquals(childLogger.getEffectiveLevel(), log4javascript.Level.ERROR);
219 });
220
221 s.test("Logger getEffectiveLevel inheritance test 3", function(t) {
222 var parentLogger = log4javascript.getLogger("test1");
223 var childLogger = log4javascript.getLogger("test1.test2");
224 parentLogger.setLevel(log4javascript.Level.ERROR);
225 childLogger.setLevel(log4javascript.Level.INFO);
226 t.assertEquals(childLogger.getEffectiveLevel(), log4javascript.Level.INFO);
227 });
228
229 s.test("Logger getEffectiveLevel root inheritance test", function(t) {
230 var rootLogger = log4javascript.getRootLogger();
231 var childLogger = log4javascript.getLogger("test1.test2.test3");
232 rootLogger.setLevel(log4javascript.Level.WARN);
233 t.assertEquals(childLogger.getEffectiveLevel(), log4javascript.Level.WARN);
234 });
235
236 s.test("Logger null level test", function(t) {
237 t.logger.setLevel(null);
238 // Should default to root logger level, which is DEBUG
239 t.assertEquals(t.logger.getEffectiveLevel(), log4javascript.Level.DEBUG);
240 });
241
242 s.test("Logger appender additivity test 1", function(t) {
243 var parentLogger = log4javascript.getLogger("test1");
244 var childLogger = log4javascript.getLogger("test1.test2");
245 var parentLoggerAppender = new ArrayAppender();
246 var childLoggerAppender = new ArrayAppender();
247
248 parentLogger.addAppender(parentLoggerAppender);
249 childLogger.addAppender(childLoggerAppender);
250
251 parentLogger.info("Parent logger test message");
252 childLogger.info("Child logger test message");
253
254 t.assertEquals(parentLoggerAppender.logMessages.length, 2);
255 t.assertEquals(childLoggerAppender.logMessages.length, 1);
256 });
257
258 s.test("Logger appender additivity test 2", function(t) {
259 var parentLogger = log4javascript.getLogger("test1");
260 var childLogger = log4javascript.getLogger("test1.test2");
261 var parentLoggerAppender = new ArrayAppender();
262 var childLoggerAppender = new ArrayAppender();
263
264 parentLogger.addAppender(parentLoggerAppender);
265 childLogger.addAppender(childLoggerAppender);
266
267 childLogger.setAdditivity(false);
268
269 parentLogger.info("Parent logger test message");
270 childLogger.info("Child logger test message");
271
272 t.assertEquals(parentLoggerAppender.logMessages.length, 1);
273 t.assertEquals(childLoggerAppender.logMessages.length, 1);
274 });
275
276 s.test("Logger appender additivity test 3", function(t) {
277 var parentLogger = log4javascript.getLogger("test1");
278 var childLogger = log4javascript.getLogger("test1.test2");
279 var parentLoggerAppender = new ArrayAppender();
280 var childLoggerAppender = new ArrayAppender();
281
282 parentLogger.addAppender(parentLoggerAppender);
283 childLogger.addAppender(childLoggerAppender);
284
285 childLogger.setAdditivity(false);
286
287 parentLogger.info("Parent logger test message");
288 childLogger.info("Child logger test message");
289
290 childLogger.setAdditivity(true);
291
292 childLogger.info("Child logger test message 2");
293
294 t.assertEquals(parentLoggerAppender.logMessages.length, 2);
295 t.assertEquals(childLoggerAppender.logMessages.length, 2);
296 });
297
298 s.test("Appender threshold test", function(t) {
299 t.appender.setThreshold(log4javascript.Level.INFO);
300 t.logger.debug("TEST");
301 t.assertEquals(t.appender.logMessages.length, 0);
302 });
303
304 s.test("Basic appender / layout test", function(t) {
305 t.logger.debug("TEST");
306 t.assertEquals(t.appender.logMessages[0], "TEST");
307 });
308
309 s.test("Appender uniqueness within logger test", function(t) {
310 // Add the same appender to the logger for a second time
311 t.logger.addAppender(t.appender);
312 t.logger.debug("TEST");
313 t.assertEquals(t.appender.logMessages.length, 1);
314 });
315
316 s.test("Logger remove appender test", function(t) {
317 t.logger.debug("TEST");
318 t.logger.removeAppender(t.appender);
319 t.logger.debug("TEST AGAIN");
320 t.assertEquals(t.appender.logMessages.length, 1);
321 });
322
323 s.test("", function(t) {
324 t.logger.debug("TEST");
325 t.logger.removeAppender(t.appender);
326 t.logger.debug("TEST AGAIN");
327 t.assertEquals(t.appender.logMessages.length, 1);
328 });
329 s.test("SimpleLayout format test", function(t) {
330 var layout = new log4javascript.SimpleLayout();
331 testLayoutWithVariables(layout, t);
332 });
333
334 s.test("SimpleLayout test", function(t) {
335 t.appender.setLayout(new log4javascript.SimpleLayout());
336 t.logger.debug("TEST");
337 t.assertEquals(t.appender.logMessages[0], "DEBUG - TEST");
338 });
339 s.test("NullLayout format test", function(t) {
340 var layout = new log4javascript.NullLayout();
341 testLayoutWithVariables(layout, t);
342 });
343
344 s.test("NullLayout test", function(t) {
345 t.appender.setLayout(new log4javascript.NullLayout());
346 t.logger.debug("TEST");
347 t.assertEquals(t.appender.logMessages[0], "TEST");
348 });
349 s.test("XmlLayout format test", function(t) {
350 var layout = new log4javascript.XmlLayout();
351 testLayoutWithVariables(layout, t);
352 });
353
354 s.test("XmlLayout test", function(t) {
355 t.appender.setLayout(new log4javascript.XmlLayout());
356 t.logger.debug("TEST");
357 t.assertRegexMatches(/^<log4javascript:event logger="test" timestamp="\d+" level="DEBUG">\s*<log4javascript:message><!\[CDATA\[TEST\]\]><\/log4javascript:message>\s*<\/log4javascript:event>\s*$/, t.appender.logMessages[0]);
358 });
359
360 s.test("XmlLayout with exception test", function(t) {
361 t.appender.setLayout(new log4javascript.XmlLayout());
362 t.logger.debug("TEST", new Error("Test error"));
363 t.assertRegexMatches(/^<log4javascript:event logger="test" timestamp="\d+" level="DEBUG">\s*<log4javascript:message><!\[CDATA\[TEST\]\]><\/log4javascript:message>\s*<log4javascript:exception>\s*<!\[CDATA\[.*\]\]><\/log4javascript:exception>\s*<\/log4javascript:event>\s*$/, t.appender.logMessages[0]);
364 });
365
366 var setUpXmlLayoutMillisecondsTest = function(t) {
367 t.date = new Date();
368 t.timeInMilliseconds = t.date.getTime();
369 t.timeInSeconds = Math.floor(t.timeInMilliseconds / 1000);
370 t.milliseconds = t.date.getMilliseconds();
371
372 t.loggingEvent = new log4javascript.LoggingEvent(t.logger, t.date, log4javascript.Level.DEBUG, ["TEST"], null);
373 t.layout = new log4javascript.XmlLayout();
374 }
375
376 s.test("XmlLayout seconds/milliseconds test 1", function(t) {
377 setUpXmlLayoutMillisecondsTest(t);
378
379 // Test default (i.e. timestamps in milliseconds) first
380 var regex = new RegExp('^<log4javascript:event logger="test" timestamp="' + t.timeInMilliseconds + '" level="DEBUG">\\s*<log4javascript:message><!\\[CDATA\\[TEST\\]\\]></log4javascript:message>\\s*</log4javascript:event>\\s*$');
381 t.assertRegexMatches(regex, t.layout.format(t.loggingEvent));
382 });
383
384 s.test("XmlLayout seconds/milliseconds test 2", function(t) {
385 setUpXmlLayoutMillisecondsTest(t);
386
387 // Change the global setting
388 log4javascript.setTimeStampsInMilliseconds(false);
389 var formatted = t.layout.format(t.loggingEvent);
390 log4javascript.setTimeStampsInMilliseconds(true);
391 var regex = new RegExp('^<log4javascript:event logger="test" timestamp="' + t.timeInSeconds + '" milliseconds="' + t.milliseconds + '" level="DEBUG">\\s*<log4javascript:message><!\\[CDATA\\[TEST\\]\\]></log4javascript:message>\\s*</log4javascript:event>\\s*$');
392 t.assertRegexMatches(regex, formatted);
393 });
394
395 s.test("XmlLayout seconds/milliseconds test 3", function(t) {
396 setUpXmlLayoutMillisecondsTest(t);
397
398 // Change the layout setting
399 t.layout.setTimeStampsInMilliseconds(false);
400 var formatted = t.layout.format(t.loggingEvent);
401 var regex = new RegExp('^<log4javascript:event logger="test" timestamp="' + t.timeInSeconds + '" milliseconds="' + t.milliseconds + '" level="DEBUG">\\s*<log4javascript:message><!\\[CDATA\\[TEST\\]\\]></log4javascript:message>\\s*</log4javascript:event>\\s*$');
402 t.assertRegexMatches(regex, formatted);
403 });
404 s.test("escapeNewLines test", function(t) {
405 var escapeNewLines = log4javascript.evalInScope("escapeNewLines");
406 var str = "1\r2\n3\n4\r\n5\r6\r\n7";
407 t.assertEquals(escapeNewLines(str), "1\\r\\n2\\r\\n3\\r\\n4\\r\\n5\\r\\n6\\r\\n7");
408 });
409
410 s.test("JsonLayout format test", function(t) {
411 var layout = new log4javascript.JsonLayout();
412 testLayoutWithVariables(layout, t);
413 });
414
415 s.test("JsonLayout test", function(t) {
416 t.appender.setLayout(new log4javascript.JsonLayout());
417 t.logger.debug("TEST");
418 t.assertRegexMatches(/^{"logger":"test","timestamp":\d+,"level":"DEBUG","url":".*","message":"TEST"}$/, t.appender.logMessages[0]);
419 });
420
421 s.test("JsonLayout JSON validity test", function(t) {
422 t.appender.setLayout(new log4javascript.JsonLayout());
423 t.logger.debug("TEST");
424 eval("var o = " + t.appender.logMessages[0]);
425 t.assertEquals(o.message, "TEST");
426 });
427
428 s.test("JsonLayout with number type message test", function(t) {
429 t.appender.setLayout(new log4javascript.JsonLayout());
430 t.logger.debug(15);
431 t.assertRegexMatches(/^{"logger":"test","timestamp":\d+,"level":"DEBUG","url":".*","message":15}$/, t.appender.logMessages[0]);
432 });
433
434 s.test("JsonLayout with object type message test", function(t) {
435 t.appender.setLayout(new log4javascript.JsonLayout());
436 t.logger.debug({});
437 t.assertRegexMatches(/^{"logger":"test","timestamp":\d+,"level":"DEBUG","url":".*","message":"\[object Object\]"}$/, t.appender.logMessages[0]);
438 });
439
440 s.test("JsonLayout with boolean type message test", function(t) {
441 t.appender.setLayout(new log4javascript.JsonLayout());
442 t.logger.debug(false);
443 t.assertRegexMatches(/^{"logger":"test","timestamp":\d+,"level":"DEBUG","url":".*","message":false}$/, t.appender.logMessages[0]);
444 });
445
446 s.test("JsonLayout with quote test", function(t) {
447 t.appender.setLayout(new log4javascript.JsonLayout());
448 t.logger.debug("TE\"S\"T");
449 t.assertRegexMatches(/^{"logger":"test","timestamp":\d+,"level":"DEBUG","url":".*","message":"TE\\"S\\"T"}$/, t.appender.logMessages[0]);
450 });
451
452 s.test("JsonLayout with exception test", function(t) {
453 t.appender.setLayout(new log4javascript.JsonLayout());
454 t.logger.debug("TEST", new Error("Test error"));
455 t.assertRegexMatches(/^{"logger":"test","timestamp":\d+,"level":"DEBUG","url":".*","message":"TEST","exception":.*}$/, t.appender.logMessages[0]);
456 });
457
458 var setUpJsonLayoutMillisecondsTest = function(t) {
459 t.date = new Date();
460 t.timeInMilliseconds = t.date.getTime();
461 t.timeInSeconds = Math.floor(t.timeInMilliseconds / 1000);
462 t.milliseconds = t.date.getMilliseconds();
463
464 t.loggingEvent = new log4javascript.LoggingEvent(t.logger, t.date, log4javascript.Level.DEBUG, ["TEST"], null);
465 t.layout = new log4javascript.JsonLayout();
466 };
467
468 s.test("JsonLayout seconds/milliseconds test 1", function(t) {
469 setUpJsonLayoutMillisecondsTest(t);
470
471 // Test default (i.e. timestamps in milliseconds) first
472 var regex = new RegExp('^{"logger":"test","timestamp":' + t.timeInMilliseconds + ',"level":"DEBUG","url":".*","message":"TEST"}$');
473 t.assertRegexMatches(regex, t.layout.format(t.loggingEvent));
474 });
475
476 s.test("JsonLayout seconds/milliseconds test 2", function(t) {
477 setUpJsonLayoutMillisecondsTest(t);
478
479 // Change the global setting
480 log4javascript.setTimeStampsInMilliseconds(false);
481 var formatted = t.layout.format(t.loggingEvent);
482 log4javascript.setTimeStampsInMilliseconds(true);
483 var regex = new RegExp('^{"logger":"test","timestamp":' + t.timeInSeconds + ',"level":"DEBUG","url":".*","message":"TEST","milliseconds":' + t.milliseconds + '}$');
484 t.assertRegexMatches(regex, formatted);
485 });
486
487 s.test("JsonLayout seconds/milliseconds test 3", function(t) {
488 setUpJsonLayoutMillisecondsTest(t);
489
490 // Change the layout setting
491 t.layout.setTimeStampsInMilliseconds(false);
492 var formatted = t.layout.format(t.loggingEvent);
493 var regex = new RegExp('^{"logger":"test","timestamp":' + t.timeInSeconds + ',"level":"DEBUG","url":".*","message":"TEST","milliseconds":' + t.milliseconds + '}$');
494 t.assertRegexMatches(regex, formatted);
495 });
496 s.test("HttpPostDataLayout format test", function(t) {
497 var layout = new log4javascript.HttpPostDataLayout();
498 testLayoutWithVariables(layout, t);
499 });
500
501 s.test("HttpPostDataLayout test", function(t) {
502 t.appender.setLayout(new log4javascript.HttpPostDataLayout());
503 t.logger.debug("TEST");
504 t.assertRegexMatches(/^logger=test&timestamp=\d+&level=DEBUG&url=.*&message=TEST$/, t.appender.logMessages[0]);
505 });
506
507 s.test("HttpPostDataLayout URL encoding test", function(t) {
508 t.appender.setLayout(new log4javascript.HttpPostDataLayout());
509 t.logger.debug("TEST +\"1\"");
510 t.assertRegexMatches(/^logger=test&timestamp=\d+&level=DEBUG&url=.*&message=TEST%20%2B%221%22$/, t.appender.logMessages[0]);
511 });
512
513 s.test("HttpPostDataLayout with exception test", function(t) {
514 t.appender.setLayout(new log4javascript.HttpPostDataLayout());
515 t.logger.debug("TEST", new Error("Test error"));
516 t.assertRegexMatches(/^logger=test&timestamp=\d+&level=DEBUG&url=.*&message=TEST&exception=.*$/, t.appender.logMessages[0]);
517 });
518
519 (function() {
520 var formatObjectExpansion = log4javascript.evalInScope("formatObjectExpansion");
521 var newLine = log4javascript.evalInScope("newLine");
522 var arr = [
523 null,
524 undefined,
525 1.2,
526 "A string",
527 [1, "test"],
528 {
529 a: {
530 b: 1
531 }
532 }
533 ];
534
535 s.test("Basic formatObjectExpansion array test (depth: 1)", function(t) {
536 t.assertEquals(formatObjectExpansion(arr, 1),
537 "[" + newLine +
538 " null," + newLine +
539 " undefined," + newLine +
540 " 1.2," + newLine +
541 " A string," + newLine +
542 " 1,test," + newLine +
543 " [object Object]" + newLine +
544 "]"
545 );
546 });
547
548 s.test("Basic formatObjectExpansion array test (depth: 2)", function(t) {
549 t.assertEquals(formatObjectExpansion(arr, 2),
550 "[" + newLine +
551 " null," + newLine +
552 " undefined," + newLine +
553 " 1.2," + newLine +
554 " A string," + newLine +
555 " [" + newLine +
556 " 1," + newLine +
557 " test" + newLine +
558 " ]," + newLine +
559 " {" + newLine +
560 " a: [object Object]" + newLine +
561 " }" + newLine +
562 "]"
563 );
564 });
565
566 s.test("formatObjectExpansion simple object test", function(t) {
567 var obj = {
568 STRING: "A string"
569 };
570 t.assertEquals(formatObjectExpansion(obj, 1),
571 "{" + newLine +
572 " STRING: A string" + newLine +
573 "}"
574 );
575 });
576
577 s.test("formatObjectExpansion simple circular object test", function(t) {
578 var obj = {};
579 obj.a = obj;
580
581 t.assertEquals(formatObjectExpansion(obj, 2),
582 "{" + newLine +
583 " a: [object Object] [already expanded]" + newLine +
584 "}"
585 );
586 });
587 })(); /* ---------------------------------------------------------- */
588
589 var getSampleDate = function() {
590 var date = new Date();
591 date.setFullYear(2006);
592 date.setMonth(7);
593 date.setDate(30);
594 date.setHours(15);
595 date.setMinutes(38);
596 date.setSeconds(45);
597 return date;
598 };
599
600 /* ---------------------------------------------------------- */
601
602 s.test("String.replace test", function(t) {
603 t.assertEquals("Hello world".replace(/o/g, "Z"), "HellZ wZrld");
604 });
605
606 s.test("PatternLayout format test", function(t) {
607 var layout = new log4javascript.PatternLayout();
608 testLayoutWithVariables(layout, t);
609 });
610
611 s.test("PatternLayout dates test", function(t) {
612 var layout = new log4javascript.PatternLayout("%d %d{DATE} %d{HH:ss}");
613 t.appender.setLayout(layout);
614 t.logger.debug("TEST");
615 t.assertRegexMatches(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3} \d{2} [A-Z][a-z]{2} \d{4} \d{2}:\d{2}:\d{2},\d{3} \d{2}:\d{2}$/, t.appender.logMessages[0]);
616 });
617
618 s.test("PatternLayout modifiers test", function(t) {
619 var layout = new log4javascript.PatternLayout("%m|%3m|%-3m|%6m|%-6m|%.2m|%1.2m|%6.8m|%-1.2m|%-6.8m|");
620 t.appender.setLayout(layout);
621 t.logger.debug("TEST");
622 t.assertEquals(t.appender.logMessages[0], "TEST|TEST|TEST| TEST|TEST |ST|ST| TEST|ST|TEST |");
623 });
624
625 s.test("PatternLayout conversion characters test", function(t) {
626 var layout = new log4javascript.PatternLayout("%c %n %p %r literal %%");
627 t.appender.setLayout(layout);
628 t.logger.debug("TEST");
629 t.assertRegexMatches(/^test \s+ DEBUG \d+ literal %$/, t.appender.logMessages[0]);
630 });
631
632 s.test("PatternLayout message test", function(t) {
633 var layout = new log4javascript.PatternLayout("%m{1} %m{2}");
634 t.appender.setLayout(layout);
635 var testObj = {
636 strikers: {
637 quick: "Marlon"
638 }
639 };
640 t.logger.debug(testObj);
641 t.assertEquals("{\r\n strikers: [object Object]\r\n} {\r\n\ strikers: {\r\n quick: Marlon\r\n }\r\n}", t.appender.logMessages[0]);
642 });
643 // Tests for exceptions when logging
644 s.test("Logging/grouping test", function(t) {
645 var browserConsoleAppender = new log4javascript.BrowserConsoleAppender();
646 t.logger.addAppender(browserConsoleAppender);
647
648 // Test each level
649 t.logger.trace("TEST TRACE");
650 t.logger.debug("TEST DEBUG");
651 t.logger.info("TEST INFO");
652 t.logger.warn("TEST WARN");
653 t.logger.error("TEST ERROR");
654 t.logger.fatal("TEST FATAL");
655
656 // Test with exception
657 t.logger.fatal("TEST FATAL", new Error("Fake error"));
658
659 // Test multiple messages
660 t.logger.info("TEST INFO", "Second message", ["a", "b", "c"]);
661
662 // Test groups
663 t.logger.group("TEST GROUP");
664 t.logger.info("TEST INFO");
665 t.logger.groupEnd("TEST GROUP");
666 t.logger.info("TEST INFO");
667
668 t.logger.removeAppender(browserConsoleAppender);
669 });
670
671/*
672 s.test("AjaxAppender JsonLayout single message test", function(t) {
673 t.async(10000);
674 // Create and add an Ajax appender
675 var ajaxAppender = new log4javascript.AjaxAppender("../log4javascript.do");
676 ajaxAppender.setLayout(new log4javascript.JsonLayout());
677 ajaxAppender.setRequestSuccessCallback(
678 function(xmlHttp) {
679 // Response comes back as JSON array of messages logged
680 var jsonResponse = xmlHttp.responseText;
681 var arr = eval(jsonResponse);
682 t.assertEquals(arr.length, 1);
683 t.assertEquals(arr[0], "TEST");
684 t.succeed();
685 }
686 );
687 ajaxAppender.setFailCallback(
688 function(msg) {
689 t.fail(msg);
690 ajaxErrorMessage = msg;
691 }
692 );
693 t.logger.addAppender(ajaxAppender);
694 t.logger.debug("TEST");
695 });
696
697 s.test("AjaxAppender JsonLayout batched messages test", function(t) {
698 t.async(10000);
699 var message1 = "TEST 1";
700 var message2 = "String with \"lots of 'quotes'\" + plusses in";
701 var message3 = "A non-threatening string";
702 // Create and add an Ajax appender
703 var ajaxAppender = new log4javascript.AjaxAppender("../log4javascript.do");
704 ajaxAppender.setLayout(new log4javascript.JsonLayout());
705 ajaxAppender.setBatchSize(3);
706 ajaxAppender.setRequestSuccessCallback(
707 function(xmlHttp) {
708 // Response comes back as JSON array of messages logged
709 var jsonResponse = xmlHttp.responseText;
710 var arr = eval(jsonResponse);
711 t.assertEquals(arr.length, 3);
712 t.assertEquals(arr[0], message1);
713 t.assertEquals(arr[1], message2);
714 t.assertEquals(arr[2], message3);
715 t.succeed();
716 }
717 );
718 ajaxAppender.setFailCallback(
719 function(msg) {
720 t.fail(msg);
721 ajaxErrorMessage = msg;
722 }
723 );
724 t.logger.addAppender(ajaxAppender);
725 t.logger.debug(message1);
726 t.logger.info(message2);
727 t.logger.warn(message3);
728 });
729
730 s.test("AjaxAppender HttpPostDataLayout single message test", function(t) {
731 t.async(10000);
732 // Create and add an Ajax appender
733 var ajaxAppender = new log4javascript.AjaxAppender("../log4javascript.do");
734 var testMessage = "TEST +\"1\"";
735 ajaxAppender.setLayout(new log4javascript.HttpPostDataLayout());
736 ajaxAppender.setRequestSuccessCallback(
737 function(xmlHttp) {
738 // Response comes back as JSON array of messages logged
739 var jsonResponse = xmlHttp.responseText;
740 var arr = eval(jsonResponse);
741 t.assertEquals(arr.length, 1);
742 t.assertEquals(arr[0], testMessage);
743 t.succeed();
744 }
745 );
746 ajaxAppender.setFailCallback(
747 function(msg) {
748 t.fail(msg);
749 ajaxErrorMessage = msg;
750 }
751 );
752 t.logger.addAppender(ajaxAppender);
753 t.logger.debug(testMessage);
754 });
755*/
756 var testConsoleAppender = function(t, appender) {
757 var timeoutCallback = function() {
758 //alert("Failed. Debug messages follow.");
759 //log4javascript.logLog.displayDebug();
760 return (windowLoaded ? "Timed out while waiting for messages to appear" :
761 "Timed out while waiting for window to load") + ". Debug messages: " +
762 log4javascript.logLog.debugMessages.join("\r\n");
763 }
764
765 t.async(60000, timeoutCallback);
766
767 var windowLoaded = false;
768 var domChecked = false;
769
770 // Set a timeout to allow the pop-up to appear
771 var onLoadHandler = function() {
772 log4javascript.logLog.debug("onLoadHandler");
773 windowLoaded = true;
774 var win = appender.getConsoleWindow();
775
776 if (win && win.loaded) {
777 // Check that the log container element contains the log message. Since
778 // the console window waits 100 milliseconds before actually rendering the
779 // message as a DOM element, we need to use a timer
780 var checkDom = function() {
781 log4javascript.logLog.debug("checkDom");
782 domChecked = true;
783 var logContainer = win.logMainContainer;
784 if (logContainer.hasChildNodes()) {
785 if (logContainer.innerHTML.indexOf("TEST MESSAGE") == -1) {
786 appender.close();
787 t.fail("Log message not correctly logged (log container innerHTML: " + logContainer.innerHTML + ")");
788 } else {
789 t.assert(appender.isVisible());
790 appender.close();
791 t.assert(!appender.isVisible());
792 t.succeed();
793 }
794 } else {
795 appender.close();
796 t.fail("Console has no log messages");
797 }
798 }
799 window.setTimeout(checkDom, 300);
800 } else {
801 appender.close();
802 t.fail("Console mistakenly raised load event");
803 }
804 }
805
806 appender.addEventListener("load", onLoadHandler);
807 t.logger.addAppender(appender);
808 t.logger.debug("TEST MESSAGE");
809 };
810
811 s.test("InlineAppender test", function(t) {
812 var inlineAppender = new log4javascript.InlineAppender();
813 inlineAppender.setInitiallyMinimized(false);
814 inlineAppender.setNewestMessageAtTop(false);
815 inlineAppender.setScrollToLatestMessage(true);
816 inlineAppender.setWidth(600);
817 inlineAppender.setHeight(200);
818
819 testConsoleAppender(t, inlineAppender);
820 });
821
822 s.test("InPageAppender with separate console HTML file test", function(t) {
823 var inPageAppender = new log4javascript.InPageAppender();
824 inPageAppender.setInitiallyMinimized(false);
825 inPageAppender.setNewestMessageAtTop(false);
826 inPageAppender.setScrollToLatestMessage(true);
827 inPageAppender.setUseDocumentWrite(false);
828 inPageAppender.setWidth(600);
829 inPageAppender.setHeight(200);
830
831 testConsoleAppender(t, inPageAppender);
832 });
833
834 s.test("PopUpAppender test", function(t) {
835 var popUpAppender = new log4javascript.PopUpAppender();
836 popUpAppender.setFocusPopUp(true);
837 popUpAppender.setUseOldPopUp(false);
838 popUpAppender.setNewestMessageAtTop(false);
839 popUpAppender.setScrollToLatestMessage(true);
840 popUpAppender.setComplainAboutPopUpBlocking(false);
841 popUpAppender.setWidth(600);
842 popUpAppender.setHeight(200);
843
844 testConsoleAppender(t, popUpAppender);
845
846
847 });
848
849 s.test("PopUpAppender with separate console HTML file test", function(t) {
850 var popUpAppender = new log4javascript.PopUpAppender();
851 popUpAppender.setFocusPopUp(true);
852 popUpAppender.setUseOldPopUp(false);
853 popUpAppender.setNewestMessageAtTop(false);
854 popUpAppender.setScrollToLatestMessage(true);
855 popUpAppender.setComplainAboutPopUpBlocking(false);
856 popUpAppender.setUseDocumentWrite(false);
857 popUpAppender.setWidth(600);
858 popUpAppender.setHeight(200);
859
860 testConsoleAppender(t, popUpAppender);
861 });
862});