/*jshint globalstrict:false, strict:false */ //////////////////////////////////////////////////////////////////////////////// /// @brief tests for Foxx console /// /// @file /// /// DISCLAIMER /// /// Copyright 2015 triagens GmbH, Cologne, Germany /// /// Licensed under the Apache License, Version 2.0 (the "License"); /// you may not use this file except in compliance with the License. /// You may obtain a copy of the License at /// /// http://www.apache.org/licenses/LICENSE-2.0 /// /// Unless required by applicable law or agreed to in writing, software /// distributed under the License is distributed on an "AS IS" BASIS, /// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. /// See the License for the specific language governing permissions and /// limitations under the License. /// /// Copyright holder is triAGENS GmbH, Cologne, Germany /// /// @author Alan Plum /// @author Copyright 2015, triAGENS GmbH, Cologne, Germany //////////////////////////////////////////////////////////////////////////////// var jsunity = require('jsunity'); var expect = require('chai').expect; var util = require('util'); var Console = require('@arangodb/foxx/legacy/console').Console; var db = require('@arangodb').db; var qb = require('aqb'); var internal = require('internal'); var AssertionError = require('assert').AssertionError; var mountPath = '##TEST##'; function clear () { 'use strict'; if (!db._foxxlog) { return []; } return db._query( qb.for('entry').in('_foxxlog') .filter(qb.eq('entry.mount', qb.str(mountPath))) .remove('entry').in('_foxxlog') ).toArray(); } //////////////////////////////////////////////////////////////////////////////// /// @brief test suite //////////////////////////////////////////////////////////////////////////////// function ConsoleTestSuite () { 'use strict'; let console; return { //////////////////////////////////////////////////////////////////////////////// /// @brief set up //////////////////////////////////////////////////////////////////////////////// setUp: function () { console = new Console(mountPath); clear(); }, //////////////////////////////////////////////////////////////////////////////// /// @brief tear down //////////////////////////////////////////////////////////////////////////////// tearDown: function () { clear(); }, //////////////////////////////////////////////////////////////////////////////// /// @brief tests //////////////////////////////////////////////////////////////////////////////// testConsoleLogLogsMessage: function () { clear(); console.log('hi'); const logs = console.logs.list(); expect(logs.length).to.be.equal(1); expect(logs[0]).to.have.property('level', 'INFO'); expect(logs[0]).to.have.property('levelNum', console._logLevels.INFO); expect(logs[0]).to.have.property('message', 'hi'); }, testConsoleLogUsesFormat: function () { clear(); console.log('%s plus', 1, 2); const logs = console.logs.list(); expect(logs[0]).to.have.property('message', '1 plus 2'); // FIXME }, testConsoleLogLogsTime: function () { clear(); const min = Date.now(); console.log('hi'); const max = Date.now(); const logs = console.logs.list(); expect(logs[0]).to.have.property('time'); expect(logs[0].time).to.be.a('number'); expect(logs[0].time).not.to.be.lessThan(min); expect(logs[0].time).not.to.be.greaterThan(max); }, testConsoleTimeLogsDuration: function () { clear(); const start = Date.now(); console.time('hi'); const min = Date.now(); internal.sleep(0.5); const max = Date.now(); console.timeEnd('hi'); const end = Date.now(); expect(max).to.be.greaterThan(min); // sanity checking const logs = console.logs.list(); const match = logs[0].message.match(/^([^:]+):\s+(\d+)ms$/); expect(match).to.be.ok; expect(match[1]).to.equal('hi'); const elapsed = Number(match[2]); expect(elapsed).not.to.be.lessThan(max - min); expect(elapsed).not.to.be.greaterThan(end - start); }, testConsoleTimeThrowsForInvalidLabel: function () { expect(function () { console.timeEnd('this is a label that does not exist'); }).to.throw(Error); }, testConsoleDirUsesInspect: function () { const args = [ 'lol', {_PRINT: function (ctx) {ctx.output += 'hello';}} ]; args.forEach(function (arg) { clear(); console.dir(arg); const log = console.logs.list()[0]; expect(log).to.have.property('message', util.inspect(arg)); }); }, testConsoleAssertDoesNotThrow: function () { clear(); console.setAssertThrows(false); expect(function () { console.assert(false, 'potato'); }).not.to.throw(Error); const logs = console.logs.list(); expect(logs.length).to.equal(1); expect(logs[0]).to.have.property('level', 'ERROR'); expect(logs[0]).to.have.property('levelNum', console._logLevels.ERROR); expect(logs[0].message).to.match(/AssertionError: potato/); }, testConsoleAssertThrows: function () { clear(); console.setAssertThrows(true); expect(function () { console.assert(false, 'potato'); }).to.throw(AssertionError).with.property('message', 'potato'); const logs = console.logs.list(); expect(logs.length).to.equal(1); expect(logs[0].message).to.match(/AssertionError: potato/); }, testConsoleLogLevelPreventsLogging: function () { clear(); console._logLevels.POTATO = -999; console.setLogLevel(-2); console.log.level = 'POTATO'; console.log('potato'); console.log.level = 'INFO'; delete console._logLevels.POTATO; const logs = console.logs.list(); expect(logs).to.be.empty; }, testConsoleTracingAddsInfo: function () { clear(); console.setTracing(false); console.log('without tracing'); let logs = console.logs.list(); expect(logs.length).to.equal(1); expect(logs[0]).not.to.have.property('stack'); clear(); console.setTracing(true); console.log('with tracing'); console.setTracing(false); logs = console.logs.list(); expect(logs.length).to.equal(1); expect(logs[0]).to.have.property('stack'); expect(logs[0].stack).to.be.an('array'); expect(logs[0].stack[0]).to.have.property('fileName'); expect(logs[0].stack[0]).to.have.property('lineNumber'); expect(logs[0].stack[0]).to.have.property('columnNumber'); }, testCustomLogLevels: function () { clear(); const log = console.custom('BATMAN', 9000); log('potato'); const logs = console.logs.list(); expect(logs.length).to.equal(1); expect(logs[0]).to.have.property('level', 'BATMAN'); expect(logs[0]).to.have.property('levelNum', 9000); expect(logs[0]).to.have.property('message', 'potato'); }, testTrace: function () { clear(); console.trace('wat'); const logs = console.logs.list(); expect(logs.length).to.equal(1); expect(logs[0]).to.have.property('level', 'TRACE'); expect(logs[0]).to.have.property('levelNum', console._logLevels.TRACE); expect(logs[0].message).to.match(/^Trace: wat\n\s+at/); }, testLogsListWithMinLevel: function () { clear(); let logs; console.debug('lol'); console.error('hey'); logs = console.logs.list({minLevel: 'DEBUG'}); expect(logs.length).to.be.equal(2); logs = console.logs.list({minLevel: console._logLevels.DEBUG + 1}); expect(logs.length).to.be.equal(1); expect(logs[0]).to.have.property('message', 'hey'); logs = console.logs.list({minLevel: console._logLevels.ERROR + 1}); expect(logs.length).to.be.equal(0); }, testLogsListWithLevel: function () { clear(); let logs; console.debug('lol'); console.error('hey'); logs = console.logs.list({level: 'DEBUG'}); expect(logs.length).to.be.equal(1); expect(logs[0]).to.have.property('message', 'lol'); }, testLogsSearchByFileNameFailsWithoutTracing: function () { console.setTracing(false); expect(function () { console.logs.searchByFileName('lol'); }).to.throw(Error).with.property('message', 'Tracing must be enabled in order to search by filename.'); }, testLogsSearchByFileName: function () { clear(); console.setTracing(true); db._foxxlog.save({ mount: mountPath, time: Date.now(), stack: [ {fileName: 'abcdef'} ] }); expect(console.logs.searchByFileName('bcd')).to.have.property('length', 1); expect(console.logs.searchByFileName('ab')).to.have.property('length', 1); expect(console.logs.searchByFileName('ef')).to.have.property('length', 1); expect(console.logs.searchByFileName('fail')).to.have.property('length', 0); }, testLogsSearchByMessage: function () { clear(); console.log('abcdef'); expect(console.logs.searchByMessage('bcd')).to.have.property('length', 1); expect(console.logs.searchByMessage('ab')).to.have.property('length', 1); expect(console.logs.searchByMessage('ef')).to.have.property('length', 1); expect(console.logs.searchByMessage('fail')).to.have.property('length', 0); } }; } //////////////////////////////////////////////////////////////////////////////// /// @brief executes the test suite //////////////////////////////////////////////////////////////////////////////// jsunity.run(ConsoleTestSuite); return jsunity.done();