UNPKG

8.2 kBJavaScriptView Raw
1"use strict";
2
3if (typeof window === "undefined") {
4 window = {};
5}
6
7var logMethods = [
8 "trace",
9 "debug",
10 "info",
11 "warn",
12 "error"
13];
14
15define(function () {
16 function getStorageKey(loggerName) {
17 var key = "loglevel";
18 if (loggerName) {
19 key += ":" + loggerName;
20 }
21 return key;
22 }
23
24 var self = {};
25
26 // Jasmine matcher to check the log level of a log object. Usage:
27 // expect(log).toBeAtLevel("DEBUG");
28 self.toBeAtLevel = function toBeAtLevel() {
29 return {
30 compare: function (log, level) {
31 var expectedWorkingCalls = log.levels.SILENT - log.levels[level.toUpperCase()];
32 var realLogMethod = window.console.log;
33 var priorCalls = realLogMethod.calls.count();
34
35 for (var ii = 0; ii < logMethods.length; ii++) {
36 var methodName = logMethods[ii];
37 log[methodName](methodName);
38 }
39
40 var actualCalls = realLogMethod.calls.count() - priorCalls;
41 var actualLevel = logMethods[log.levels.SILENT - actualCalls];
42 return {
43 pass: actualCalls === expectedWorkingCalls,
44 message: "Expected level to be '" + level + "' but found '" + actualLevel + "'"
45 };
46 }
47 };
48 };
49
50 self.isCookieStorageAvailable = function isCookieStorageAvailable() {
51 if (window && window.document && window.document.cookie != null) {
52 // We need to check not just that the cookie objects are available, but that they work, because
53 // if we run from file:// URLs they appear present but are non-functional
54 window.document.cookie = "test=hi;";
55
56 var result = window.document.cookie.indexOf('test=hi') !== -1;
57 window.document.cookie = "test=; expires=Thu, 01 Jan 1970 00:00:01 GMT;";
58
59 return result;
60 } else {
61 return false;
62 }
63 };
64
65 self.isLocalStorageAvailable = function isLocalStorageAvailable() {
66 try {
67 return !!window.localStorage;
68 } catch (e){
69 return false;
70 }
71 };
72
73 self.isAnyLevelStoragePossible = function isAnyLevelStoragePossible() {
74 return self.isCookieStorageAvailable() || self.isLocalStorageAvailable();
75 };
76
77 // Check whether a cookie is storing the given level for the given logger
78 // name. If level is `undefined`, this will check that it is *not* stored.
79 function isLevelInCookie(level, name) {
80 level = level === undefined ? undefined : level.toUpperCase();
81 var storageKey = encodeURIComponent(getStorageKey(name));
82
83 if(level === undefined) {
84 return window.document.cookie.indexOf(storageKey + "=") === -1;
85 } else if (window.document.cookie.indexOf(storageKey + "=" + level) !== -1) {
86 return true;
87 } else {
88 return false;
89 }
90 }
91
92 // Jasmine matcher to check whether the given log level is in a cookie.
93 // Usage: `expect("DEBUG").toBeTheLevelStoredByCookie("name-of-logger")`
94 self.toBeTheLevelStoredByCookie = function toBeTheLevelStoredByCookie() {
95 return {
96 compare: function (actual, name) {
97 return {
98 pass: isLevelInCookie(actual, name),
99 message: "Level '" + actual + "' for the " + (name || "default") + " logger is not stored in a cookie"
100 };
101 }
102 };
103 };
104
105 // Check whether local storage is storing the given level for the given
106 // logger name. If level is `undefined`, this will check that it is *not*
107 // stored.
108 function isLevelInLocalStorage(level, name) {
109 level = level === undefined ? undefined : level.toUpperCase();
110
111 if (window.localStorage[getStorageKey(name)] === level) {
112 return true;
113 }
114
115 return false;
116 }
117
118 // Jasmine matcher to check whether the given log level is in local storage.
119 // Usage: `expect("DEBUG").toBeTheLevelStoredByLocalStorage("name-of-logger")`
120 self.toBeTheLevelStoredByLocalStorage = function toBeTheLevelStoredByLocalStorage() {
121 return {
122 compare: function (actual, name) {
123 return {
124 pass: isLevelInLocalStorage(actual, name),
125 message: "Level '" + actual + "' for the " + (name || "default") + " logger is not stored in local storage"
126 };
127 }
128 };
129 };
130
131 // Jasmine matcher to check whether a given level has been persisted.
132 self.toBeTheStoredLevel = function toBeTheStoredLevel() {
133 return {
134 compare: function (actual, name) {
135 return {
136 pass: isLevelInLocalStorage(actual, name) ||
137 isLevelInCookie(actual, name),
138 message: "Level '" + actual + "' is not persisted for the " + (name || "default") + " logger"
139 };
140 }
141 };
142 };
143
144 self.setCookieStoredLevel = function setCookieStoredLevel(level, name) {
145 window.document.cookie =
146 encodeURIComponent(getStorageKey(name)) + "=" +
147 level.toUpperCase() + ";";
148 };
149
150 self.setLocalStorageStoredLevel = function setLocalStorageStoredLevel(level, name) {
151 window.localStorage[getStorageKey(name)] = level.toUpperCase();
152 };
153
154 self.setStoredLevel = function setStoredLevel(level, name) {
155 if (self.isCookieStorageAvailable()) {
156 self.setCookieStoredLevel(level, name);
157 }
158 if (self.isLocalStorageAvailable()) {
159 self.setLocalStorageStoredLevel(level, name);
160 }
161 };
162
163 self.clearStoredLevels = function clearStoredLevels() {
164 if (self.isLocalStorageAvailable()) {
165 window.localStorage.clear();
166 }
167 if (self.isCookieStorageAvailable()) {
168 var storedKeys = window.document.cookie.match(/(?:^|;\s)(loglevel(%3a\w+)?)(?=\=)/ig);
169 if (storedKeys) {
170 for (var i = 0; i < storedKeys.length; i++) {
171 window.document.cookie = storedKeys[i] + "=; expires=Thu, 01 Jan 1970 00:00:01 GMT;";
172 }
173 }
174 }
175 };
176
177 self.describeIf = function describeIf(condition, name, test) {
178 var env = jasmine.getEnv();
179 var implementation = condition ? env.describe : env.xdescribe;
180 return implementation(name, test);
181 };
182
183 self.itIf = function itIf(condition, name, test) {
184 var env = jasmine.getEnv();
185 var implementation = condition ? env.it : env.xit;
186 return implementation(name, test);
187 };
188
189 // Forcibly reloads loglevel and asynchronously hands the resulting log to
190 // a callback.
191 self.withFreshLog = function withFreshLog(toRun, onError) {
192 require.undef("lib/loglevel");
193
194 require(['lib/loglevel'], function(log) {
195 toRun(log);
196 });
197 };
198
199 // Wraps Jasmine's `it(name, test)` call to reload the loglevel module
200 // for the given test. An optional boolean first argument causes this to
201 // behave like `itIf()` instead of `it()`.
202 //
203 // Normal usage:
204 // itWithFreshLog("test name", function(log) {
205 // // test code
206 // });
207 //
208 // Conditional usage:
209 // itWithFreshLog(shouldRunTest(), "test name", function(log) {
210 // // test code
211 // });
212 self.itWithFreshLog = function itWithFreshLog(condition, name, test) {
213 if (!test) {
214 test = name;
215 name = condition;
216 condition = true;
217 }
218
219 self.itIf(condition, name, function(done) {
220 function runTest (log) {
221 if (test.length > 1) {
222 return test(log, done);
223 } else {
224 try {
225 test(log);
226 done();
227 } catch (error) {
228 done.fail(error);
229 }
230 }
231 }
232 self.withFreshLog(runTest);
233 });
234 };
235
236 return self;
237});