(function() {
'use strict';
angular.module('fef',['ngResource'])
.provider('fefLogger', FefLogProvider);
function FefLogProvider() {
var config = {
consoleThreshold: 4,
httpThreshold: 1,
httpDomain: undefined,
httpPath: '/demo/logs',
delay: 250
};
var resource;
var rootname = 'fef';
var rootGuid = trmrguid();
var $window, $location;
function setInit(_window, _location) {
$window = _window;
$location = _location;
}
function formatError(arg, name) {
if (arg instanceof Error) {
if (arg.stack) {
arg = (arg.message && arg.stack.indexOf(arg.message) === -1) ? 'Error: ' +
arg.message + '\n' + arg.stack : arg.stack;
} else if (arg.sourceURL) {
arg = arg.message + '\n' + arg.sourceURL + ':' + arg.line;
}
}
return '[' + name+ '] ' + arg;
}
function consoleLog(type, parent, name) {
var console = $window.console || {},
logFn = console[type] || console.log || angular.noop;
if (logFn.apply) {
var args = [];
angular.forEach(parent, function(arg) {
args.push(formatError(arg, name));
});
logFn.apply(console, args);
}
}
function configure(_conf) {
if (!_conf.consoleThreshold || !(_conf.consoleThreshold >= 1 && _conf.consoleThreshold <= 5)) {
_conf.consoleThreshold = 4;
}
if (!_conf.httpThreshold || !(_conf.httpThreshold >= 1 && _conf.httpThreshold <= 5)) {
_conf.httpThreshold = 1;
}
var keys = Object.keys(config);
angular.forEach(keys, function (item) {
if(_conf[item]){
config[item] = _conf[item];
}
});
}
function setResource(_resouce) {
resource = _resouce;
}
function formatMessage(_type, level, name) {
return function () {
var timestamp = (new Date()).toISOString();
var module = rootname;
if (name) {
module = module + ':' + name;
}
var log = {
root: rootGuid,
timestamp: timestamp,
message: [].slice.call(arguments) || '',
level: _type,
url: $location.absUrl(),
name: module
};
if (arguments[0] instanceof Error && window.printStackTrace) {
log.stacktrace = window.printStackTrace({
e: arguments[0]
});
}
if (config.httpPath && level <= config.httpThreshold) {
resource.save(log);
}
if (level <= config.consoleThreshold) {
switch (level) {
case 5:
consoleLog('debug',arguments, module);
break;
case 4:
consoleLog('log',arguments, module);
break;
case 3:
consoleLog('info',arguments, module);
break;
case 2:
consoleLog('warn',arguments, module);
break;
case 1:
consoleLog('error',arguments, module);
break;
}
}
};
}
/*jshint bitwise: true*/
function trmrguid() {
return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0,
v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
return {
configure: configure,
$get: ['$resource', '$location', '$window', function($resource, $location,$window) {
var urlPath = config.httpPath;
if(config.httpDomain){
urlPath = 'http://' + config.httpDomain + urlPath;
}
var WS = $resource(urlPath,
null, {
save: {
method: 'POST',
headers: {
common: {
'x-cobalt-pcid': trmrguid()
}
}
}
});
setResource(WS);
setInit($window, $location);
return {
debug: formatMessage('debug', 5),
log: formatMessage('log', 4),
info: formatMessage('info', 3),
warn: formatMessage('warn', 2),
error: formatMessage('error', 1),
getLogger: function(value) {
if (arguments.length > 1) {
var temp = Array.apply(null, arguments);
value = temp.join(':');
}
return {
debug: formatMessage('debug', 5, value),
log: formatMessage('log', 4,value),
info: formatMessage('info', 3, value),
warn: formatMessage('warn', 2, value),
error: formatMessage('error', 1, value)
};
}
};
}]
};
}
}());
describe('FefLogger with config setting the httpThreshold.', function() {
var FefLogger, httpBackend, rootScope, message;
beforeEach(module('fef'));
beforeEach(module('ngResource'));
beforeEach(function() {
var myModule = angular.module('fef');
myModule.config(function(fefLoggerProvider) {
fefLoggerProvider.configure({
httpThreshold: 4,
consoleThreshold: 1
});
});
});
var windowMock = {
navigator: {},
document: {}
};
var myConsole = {
log: function(value) {
message = value;
},
warn: function(value) {
message = value;
},
info: function(value) {
message = value;
},
error: function(value) {
message = value;
},
debug: function(value) {
message = value;
}
};
windowMock.console = myConsole;
beforeEach(module(function($provide) {
$provide.value('$window', windowMock);
}));
afterEach(function() {
message = '';
});
/*jshint camelcase: false */
beforeEach(inject(function(_fefLogger_, $httpBackend, $window, $rootScope) {
FefLogger = _fefLogger_;
spyOn(myConsole, 'error').and.callThrough();
spyOn(myConsole, 'warn').and.callThrough();
spyOn(myConsole, 'info').and.callThrough();
spyOn(myConsole, 'log').and.callThrough();
spyOn(myConsole, 'debug').and.callThrough();
httpBackend = $httpBackend;
rootScope = $rootScope;
}));
it('check to see if we can create a FefLogger', function() {
expect(!!FefLogger).toBe(true);
});
it('test log works with http call.', function() {
var success = true;
httpBackend.expectPOST('/demo/logs')
.respond(
function(method, url, data, headers) {
var validData = {
message: ['test'],
level: 'log',
name: 'fef'
};
data = JSON.parse(data);
if (data.message[0] === validData.message[0] &&
data.level === validData.level &&
data.name === validData.name) {
return [200, {
token: '12345'
}];
} else {
success = false;
return [400, {
failure: 'bad'
}];
}
});
FefLogger.log('test');
expect(myConsole.log).not.toHaveBeenCalled();
httpBackend.flush();
expect(success).toBe(true);
});
it('test debug is not called call.', function() {
var success = true;
httpBackend.expectPOST('/demo/logs')
.respond(
function(method, url, data, headers) {
var validData = {
message: ['test'],
level: 'debug',
name: 'fef'
};
data = JSON.parse(data);
if (data.message[0] === validData.message[0] &&
data.level === validData.level &&
data.name === validData.name) {
return [200, {
token: '12345'
}];
} else {
success = false;
return [400, {
failure: 'bad'
}];
}
});
FefLogger.debug('test');
expect(httpBackend.flush).toThrowError('No pending request to flush !');
});
it('test mult call is correct format.', function() {
var success = true;
httpBackend.expectPOST('/demo/logs')
.respond(
function(method, url, data, headers) {
var validData = {
message: ['test'],
level: 'log',
name: 'fef:log1'
};
data = JSON.parse(data);
if (data.message[0] === validData.message[0] &&
data.level === validData.level &&
data.name === validData.name) {
return [200, {
token: '12345'
}];
} else {
success = false;
return [400, {
failure: 'bad'
}];
}
});
var log1 = FefLogger.getLogger('log1');
log1.log('test');
httpBackend.flush();
expect(success).toBe(true);
});
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Test Template</title>
<!-- Load up Jasmine -->
<link data-require="jasmine@*" data-semver="2.0.0" rel="stylesheet" href="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine.css" />
<script data-require="jasmine@*" data-semver="2.0.0" src="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine.js"></script>
<script data-require="jasmine@*" data-semver="2.0.0" src="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine-html.js"></script>
<script data-require="jasmine@*" data-semver="2.0.0" src="//cdn.jsdelivr.net/jasmine/2.0.0/boot.js"></script>
<script src="http://code.angularjs.org/1.4.0-beta.6/angular.js"></script>
<script src="http://code.angularjs.org/1.4.0-beta.6/angular-resource.js"></script>
<script src="http://code.angularjs.org/1.4.0-beta.6/angular-mocks.js"></script>
<!-- The application code -->
<script src="app.js"></script>
<!-- The test specs -->
<script src="app.spec.js"></script>
</head>
<body>
<!-- Unit tests are displayed here -->
<div id="HTMLReporter" class="jasmine_reporter"></div>
</body>
</html>