Best Python code snippet using dbt-osmosis_python
logger.js
Source:logger.js  
1// Copyright 2006 The Closure Library Authors. All Rights Reserved.2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7//      http://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS-IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.14/**15 * @fileoverview Definition of the Logger class. Please minimize dependencies16 * this file has on other closure classes as any dependency it takes won't be17 * able to use the logging infrastructure.18 *19 * @see ../demos/debug.html20 */21goog.provide('goog.debug.LogManager');22goog.provide('goog.debug.Logger');23goog.provide('goog.debug.Logger.Level');24goog.require('goog.array');25goog.require('goog.asserts');26goog.require('goog.debug');27goog.require('goog.debug.LogBuffer');28goog.require('goog.debug.LogRecord');29/**30 * The Logger is an object used for logging debug messages. Loggers are31 * normally named, using a hierarchical dot-separated namespace. Logger names32 * can be arbitrary strings, but they should normally be based on the package33 * name or class name of the logged component, such as goog.net.BrowserChannel.34 *35 * The Logger object is loosely based on the java class36 * java.util.logging.Logger. It supports different levels of filtering for37 * different loggers.38 *39 * The logger object should never be instantiated by application code. It40 * should always use the goog.debug.Logger.getLogger function.41 *42 * @constructor43 * @param {string} name The name of the Logger.44 */45goog.debug.Logger = function(name) {46  /**47   * Name of the Logger. Generally a dot-separated namespace48   * @type {string}49   * @private50   */51  this.name_ = name;52};53/**54 * Parent Logger.55 * @type {goog.debug.Logger}56 * @private57 */58goog.debug.Logger.prototype.parent_ = null;59/**60 * Level that this logger only filters above. Null indicates it should61 * inherit from the parent.62 * @type {goog.debug.Logger.Level}63 * @private64 */65goog.debug.Logger.prototype.level_ = null;66/**67 * Map of children loggers. The keys are the leaf names of the children and68 * the values are the child loggers.69 * @type {Object}70 * @private71 */72goog.debug.Logger.prototype.children_ = null;73/**74 * Handlers that are listening to this logger.75 * @type {Array.<Function>}76 * @private77 */78goog.debug.Logger.prototype.handlers_ = null;79/**80 * @define {boolean} Toggles whether loggers other than the root logger can have81 *     log handlers attached to them and whether they can have their log level82 *     set. Logging is a bit faster when this is set to false.83 */84goog.debug.Logger.ENABLE_HIERARCHY = true;85if (!goog.debug.Logger.ENABLE_HIERARCHY) {86  /**87   * @type {!Array.<Function>}88   * @private89   */90  goog.debug.Logger.rootHandlers_ = [];91  /**92   * @type {goog.debug.Logger.Level}93   * @private94   */95  goog.debug.Logger.rootLevel_;96}97/**98 * The Level class defines a set of standard logging levels that99 * can be used to control logging output.  The logging Level objects100 * are ordered and are specified by ordered integers.  Enabling logging101 * at a given level also enables logging at all higher levels.102 * <p>103 * Clients should normally use the predefined Level constants such104 * as Level.SEVERE.105 * <p>106 * The levels in descending order are:107 * <ul>108 * <li>SEVERE (highest value)109 * <li>WARNING110 * <li>INFO111 * <li>CONFIG112 * <li>FINE113 * <li>FINER114 * <li>FINEST  (lowest value)115 * </ul>116 * In addition there is a level OFF that can be used to turn117 * off logging, and a level ALL that can be used to enable118 * logging of all messages.119 *120 * @param {string} name The name of the level.121 * @param {number} value The numeric value of the level.122 * @constructor123 */124goog.debug.Logger.Level = function(name, value) {125  /**126   * The name of the level127   * @type {string}128   */129  this.name = name;130  /**131   * The numeric value of the level132   * @type {number}133   */134  this.value = value;135};136/**137 * @return {string} String representation of the logger level.138 */139goog.debug.Logger.Level.prototype.toString = function() {140  return this.name;141};142/**143 * OFF is a special level that can be used to turn off logging.144 * This level is initialized to <CODE>Number.MAX_VALUE</CODE>.145 * @type {!goog.debug.Logger.Level}146 */147goog.debug.Logger.Level.OFF =148    new goog.debug.Logger.Level('OFF', Infinity);149/**150 * SHOUT is a message level for extra debugging loudness.151 * This level is initialized to <CODE>1200</CODE>.152 * @type {!goog.debug.Logger.Level}153 */154goog.debug.Logger.Level.SHOUT = new goog.debug.Logger.Level('SHOUT', 1200);155/**156 * SEVERE is a message level indicating a serious failure.157 * This level is initialized to <CODE>1000</CODE>.158 * @type {!goog.debug.Logger.Level}159 */160goog.debug.Logger.Level.SEVERE = new goog.debug.Logger.Level('SEVERE', 1000);161/**162 * WARNING is a message level indicating a potential problem.163 * This level is initialized to <CODE>900</CODE>.164 * @type {!goog.debug.Logger.Level}165 */166goog.debug.Logger.Level.WARNING = new goog.debug.Logger.Level('WARNING', 900);167/**168 * INFO is a message level for informational messages.169 * This level is initialized to <CODE>800</CODE>.170 * @type {!goog.debug.Logger.Level}171 */172goog.debug.Logger.Level.INFO = new goog.debug.Logger.Level('INFO', 800);173/**174 * CONFIG is a message level for static configuration messages.175 * This level is initialized to <CODE>700</CODE>.176 * @type {!goog.debug.Logger.Level}177 */178goog.debug.Logger.Level.CONFIG = new goog.debug.Logger.Level('CONFIG', 700);179/**180 * FINE is a message level providing tracing information.181 * This level is initialized to <CODE>500</CODE>.182 * @type {!goog.debug.Logger.Level}183 */184goog.debug.Logger.Level.FINE = new goog.debug.Logger.Level('FINE', 500);185/**186 * FINER indicates a fairly detailed tracing message.187 * This level is initialized to <CODE>400</CODE>.188 * @type {!goog.debug.Logger.Level}189 */190goog.debug.Logger.Level.FINER = new goog.debug.Logger.Level('FINER', 400);191/**192 * FINEST indicates a highly detailed tracing message.193 * This level is initialized to <CODE>300</CODE>.194 * @type {!goog.debug.Logger.Level}195 */196goog.debug.Logger.Level.FINEST = new goog.debug.Logger.Level('FINEST', 300);197/**198 * ALL indicates that all messages should be logged.199 * This level is initialized to <CODE>Number.MIN_VALUE</CODE>.200 * @type {!goog.debug.Logger.Level}201 */202goog.debug.Logger.Level.ALL = new goog.debug.Logger.Level('ALL', 0);203/**204 * The predefined levels.205 * @type {!Array.<!goog.debug.Logger.Level>}206 * @final207 */208goog.debug.Logger.Level.PREDEFINED_LEVELS = [209  goog.debug.Logger.Level.OFF,210  goog.debug.Logger.Level.SHOUT,211  goog.debug.Logger.Level.SEVERE,212  goog.debug.Logger.Level.WARNING,213  goog.debug.Logger.Level.INFO,214  goog.debug.Logger.Level.CONFIG,215  goog.debug.Logger.Level.FINE,216  goog.debug.Logger.Level.FINER,217  goog.debug.Logger.Level.FINEST,218  goog.debug.Logger.Level.ALL];219/**220 * A lookup map used to find the level object based on the name or value of221 * the level object.222 * @type {Object}223 * @private224 */225goog.debug.Logger.Level.predefinedLevelsCache_ = null;226/**227 * Creates the predefined levels cache and populates it.228 * @private229 */230goog.debug.Logger.Level.createPredefinedLevelsCache_ = function() {231  goog.debug.Logger.Level.predefinedLevelsCache_ = {};232  for (var i = 0, level; level = goog.debug.Logger.Level.PREDEFINED_LEVELS[i];233       i++) {234    goog.debug.Logger.Level.predefinedLevelsCache_[level.value] = level;235    goog.debug.Logger.Level.predefinedLevelsCache_[level.name] = level;236  }237};238/**239 * Gets the predefined level with the given name.240 * @param {string} name The name of the level.241 * @return {goog.debug.Logger.Level} The level, or null if none found.242 */243goog.debug.Logger.Level.getPredefinedLevel = function(name) {244  if (!goog.debug.Logger.Level.predefinedLevelsCache_) {245    goog.debug.Logger.Level.createPredefinedLevelsCache_();246  }247  return goog.debug.Logger.Level.predefinedLevelsCache_[name] || null;248};249/**250 * Gets the highest predefined level <= #value.251 * @param {number} value Level value.252 * @return {goog.debug.Logger.Level} The level, or null if none found.253 */254goog.debug.Logger.Level.getPredefinedLevelByValue = function(value) {255  if (!goog.debug.Logger.Level.predefinedLevelsCache_) {256    goog.debug.Logger.Level.createPredefinedLevelsCache_();257  }258  if (value in goog.debug.Logger.Level.predefinedLevelsCache_) {259    return goog.debug.Logger.Level.predefinedLevelsCache_[value];260  }261  for (var i = 0; i < goog.debug.Logger.Level.PREDEFINED_LEVELS.length; ++i) {262    var level = goog.debug.Logger.Level.PREDEFINED_LEVELS[i];263    if (level.value <= value) {264      return level;265    }266  }267  return null;268};269/**270 * Find or create a logger for a named subsystem. If a logger has already been271 * created with the given name it is returned. Otherwise a new logger is272 * created. If a new logger is created its log level will be configured based273 * on the LogManager configuration and it will configured to also send logging274 * output to its parent's handlers. It will be registered in the LogManager275 * global namespace.276 *277 * @param {string} name A name for the logger. This should be a dot-separated278 * name and should normally be based on the package name or class name of the279 * subsystem, such as goog.net.BrowserChannel.280 * @return {!goog.debug.Logger} The named logger.281 */282goog.debug.Logger.getLogger = function(name) {283  return goog.debug.LogManager.getLogger(name);284};285/**286 * Gets the name of this logger.287 * @return {string} The name of this logger.288 */289goog.debug.Logger.prototype.getName = function() {290  return this.name_;291};292/**293 * Adds a handler to the logger. This doesn't use the event system because294 * we want to be able to add logging to the event system.295 * @param {Function} handler Handler function to add.296 */297goog.debug.Logger.prototype.addHandler = function(handler) {298  if (goog.debug.Logger.ENABLE_HIERARCHY) {299    if (!this.handlers_) {300      this.handlers_ = [];301    }302    this.handlers_.push(handler);303  } else {304    goog.asserts.assert(!this.name_,305        'Cannot call addHandler on a non-root logger when ' +306        'goog.debug.Logger.ENABLE_HIERARCHY is false.');307    goog.debug.Logger.rootHandlers_.push(handler);308  }309};310/**311 * Removes a handler from the logger. This doesn't use the event system because312 * we want to be able to add logging to the event system.313 * @param {Function} handler Handler function to remove.314 * @return {boolean} Whether the handler was removed.315 */316goog.debug.Logger.prototype.removeHandler = function(handler) {317  var handlers = goog.debug.Logger.ENABLE_HIERARCHY ? this.handlers_ :318      goog.debug.Logger.rootHandlers_;319  return !!handlers && goog.array.remove(handlers, handler);320};321/**322 * Returns the parent of this logger.323 * @return {goog.debug.Logger} The parent logger or null if this is the root.324 */325goog.debug.Logger.prototype.getParent = function() {326  return this.parent_;327};328/**329 * Returns the children of this logger as a map of the child name to the logger.330 * @return {!Object} The map where the keys are the child leaf names and the331 *     values are the Logger objects.332 */333goog.debug.Logger.prototype.getChildren = function() {334  if (!this.children_) {335    this.children_ = {};336  }337  return this.children_;338};339/**340 * Set the log level specifying which message levels will be logged by this341 * logger. Message levels lower than this value will be discarded.342 * The level value Level.OFF can be used to turn off logging. If the new level343 * is null, it means that this node should inherit its level from its nearest344 * ancestor with a specific (non-null) level value.345 *346 * @param {goog.debug.Logger.Level} level The new level.347 */348goog.debug.Logger.prototype.setLevel = function(level) {349  if (goog.debug.Logger.ENABLE_HIERARCHY) {350    this.level_ = level;351  } else {352    goog.asserts.assert(!this.name_,353        'Cannot call setLevel() on a non-root logger when ' +354        'goog.debug.Logger.ENABLE_HIERARCHY is false.');355    goog.debug.Logger.rootLevel_ = level;356  }357};358/**359 * Gets the log level specifying which message levels will be logged by this360 * logger. Message levels lower than this value will be discarded.361 * The level value Level.OFF can be used to turn off logging. If the level362 * is null, it means that this node should inherit its level from its nearest363 * ancestor with a specific (non-null) level value.364 *365 * @return {goog.debug.Logger.Level} The level.366 */367goog.debug.Logger.prototype.getLevel = function() {368  return this.level_;369};370/**371 * Returns the effective level of the logger based on its ancestors' levels.372 * @return {goog.debug.Logger.Level} The level.373 */374goog.debug.Logger.prototype.getEffectiveLevel = function() {375  if (!goog.debug.Logger.ENABLE_HIERARCHY) {376    return goog.debug.Logger.rootLevel_;377  }378  if (this.level_) {379    return this.level_;380  }381  if (this.parent_) {382    return this.parent_.getEffectiveLevel();383  }384  goog.asserts.fail('Root logger has no level set.');385  return null;386};387/**388 * Check if a message of the given level would actually be logged by this389 * logger. This check is based on the Loggers effective level, which may be390 * inherited from its parent.391 * @param {goog.debug.Logger.Level} level The level to check.392 * @return {boolean} Whether the message would be logged.393 */394goog.debug.Logger.prototype.isLoggable = function(level) {395  return level.value >= this.getEffectiveLevel().value;396};397/**398 * Log a message. If the logger is currently enabled for the399 * given message level then the given message is forwarded to all the400 * registered output Handler objects.401 * @param {goog.debug.Logger.Level} level One of the level identifiers.402 * @param {string} msg The string message.403 * @param {Error|Object=} opt_exception An exception associated with the404 *     message.405 */406goog.debug.Logger.prototype.log = function(level, msg, opt_exception) {407  // java caches the effective level, not sure it's necessary here408  if (this.isLoggable(level)) {409    this.doLogRecord_(this.getLogRecord(level, msg, opt_exception));410  }411};412/**413 * Creates a new log record and adds the exception (if present) to it.414 * @param {goog.debug.Logger.Level} level One of the level identifiers.415 * @param {string} msg The string message.416 * @param {Error|Object=} opt_exception An exception associated with the417 *     message.418 * @return {!goog.debug.LogRecord} A log record.419 */420goog.debug.Logger.prototype.getLogRecord = function(level, msg, opt_exception) {421  if (goog.debug.LogBuffer.isBufferingEnabled()) {422    var logRecord =423        goog.debug.LogBuffer.getInstance().addRecord(level, msg, this.name_);424  } else {425    logRecord = new goog.debug.LogRecord(level, String(msg), this.name_);426  }427  if (opt_exception) {428    logRecord.setException(opt_exception);429    logRecord.setExceptionText(430        goog.debug.exposeException(opt_exception, arguments.callee.caller));431  }432  return logRecord;433};434/**435 * Log a message at the Logger.Level.SHOUT level.436 * If the logger is currently enabled for the given message level then the437 * given message is forwarded to all the registered output Handler objects.438 * @param {string} msg The string message.439 * @param {Error=} opt_exception An exception associated with the message.440 */441goog.debug.Logger.prototype.shout = function(msg, opt_exception) {442  this.log(goog.debug.Logger.Level.SHOUT, msg, opt_exception);443};444/**445 * Log a message at the Logger.Level.SEVERE level.446 * If the logger is currently enabled for the given message level then the447 * given message is forwarded to all the registered output Handler objects.448 * @param {string} msg The string message.449 * @param {Error=} opt_exception An exception associated with the message.450 */451goog.debug.Logger.prototype.severe = function(msg, opt_exception) {452  this.log(goog.debug.Logger.Level.SEVERE, msg, opt_exception);453};454/**455 * Log a message at the Logger.Level.WARNING level.456 * If the logger is currently enabled for the given message level then the457 * given message is forwarded to all the registered output Handler objects.458 * @param {string} msg The string message.459 * @param {Error=} opt_exception An exception associated with the message.460 */461goog.debug.Logger.prototype.warning = function(msg, opt_exception) {462  this.log(goog.debug.Logger.Level.WARNING, msg, opt_exception);463};464/**465 * Log a message at the Logger.Level.INFO level.466 * If the logger is currently enabled for the given message level then the467 * given message is forwarded to all the registered output Handler objects.468 * @param {string} msg The string message.469 * @param {Error=} opt_exception An exception associated with the message.470 */471goog.debug.Logger.prototype.info = function(msg, opt_exception) {472  this.log(goog.debug.Logger.Level.INFO, msg, opt_exception);473};474/**475 * Log a message at the Logger.Level.CONFIG level.476 * If the logger is currently enabled for the given message level then the477 * given message is forwarded to all the registered output Handler objects.478 * @param {string} msg The string message.479 * @param {Error=} opt_exception An exception associated with the message.480 */481goog.debug.Logger.prototype.config = function(msg, opt_exception) {482  this.log(goog.debug.Logger.Level.CONFIG, msg, opt_exception);483};484/**485 * Log a message at the Logger.Level.FINE level.486 * If the logger is currently enabled for the given message level then the487 * given message is forwarded to all the registered output Handler objects.488 * @param {string} msg The string message.489 * @param {Error=} opt_exception An exception associated with the message.490 */491goog.debug.Logger.prototype.fine = function(msg, opt_exception) {492  this.log(goog.debug.Logger.Level.FINE, msg, opt_exception);493};494/**495 * Log a message at the Logger.Level.FINER level.496 * If the logger is currently enabled for the given message level then the497 * given message is forwarded to all the registered output Handler objects.498 * @param {string} msg The string message.499 * @param {Error=} opt_exception An exception associated with the message.500 */501goog.debug.Logger.prototype.finer = function(msg, opt_exception) {502  this.log(goog.debug.Logger.Level.FINER, msg, opt_exception);503};504/**505 * Log a message at the Logger.Level.FINEST level.506 * If the logger is currently enabled for the given message level then the507 * given message is forwarded to all the registered output Handler objects.508 * @param {string} msg The string message.509 * @param {Error=} opt_exception An exception associated with the message.510 */511goog.debug.Logger.prototype.finest = function(msg, opt_exception) {512  this.log(goog.debug.Logger.Level.FINEST, msg, opt_exception);513};514/**515 * Log a LogRecord. If the logger is currently enabled for the516 * given message level then the given message is forwarded to all the517 * registered output Handler objects.518 * @param {goog.debug.LogRecord} logRecord A log record to log.519 */520goog.debug.Logger.prototype.logRecord = function(logRecord) {521  if (this.isLoggable(logRecord.getLevel())) {522    this.doLogRecord_(logRecord);523  }524};525/**526 * Logs the message to speed tracer, if it is available.527 * {@see http://code.google.com/webtoolkit/speedtracer/logging-api.html}528 * @param {string} msg The message to log.529 * @private530 */531goog.debug.Logger.prototype.logToSpeedTracer_ = function(msg) {532  if (goog.global['console'] && goog.global['console']['markTimeline']) {533    goog.global['console']['markTimeline'](msg);534  }535};536/**537 * Log a LogRecord.538 * @param {goog.debug.LogRecord} logRecord A log record to log.539 * @private540 */541goog.debug.Logger.prototype.doLogRecord_ = function(logRecord) {542  this.logToSpeedTracer_('log:' + logRecord.getMessage());543  if (goog.debug.Logger.ENABLE_HIERARCHY) {544    var target = this;545    while (target) {546      target.callPublish_(logRecord);547      target = target.getParent();548    }549  } else {550    for (var i = 0, handler; handler = goog.debug.Logger.rootHandlers_[i++]; ) {551      handler(logRecord);552    }553  }554};555/**556 * Calls the handlers for publish.557 * @param {goog.debug.LogRecord} logRecord The log record to publish.558 * @private559 */560goog.debug.Logger.prototype.callPublish_ = function(logRecord) {561  if (this.handlers_) {562    for (var i = 0, handler; handler = this.handlers_[i]; i++) {563      handler(logRecord);564    }565  }566};567/**568 * Sets the parent of this logger. This is used for setting up the logger tree.569 * @param {goog.debug.Logger} parent The parent logger.570 * @private571 */572goog.debug.Logger.prototype.setParent_ = function(parent) {573  this.parent_ = parent;574};575/**576 * Adds a child to this logger. This is used for setting up the logger tree.577 * @param {string} name The leaf name of the child.578 * @param {goog.debug.Logger} logger The child logger.579 * @private580 */581goog.debug.Logger.prototype.addChild_ = function(name, logger) {582  this.getChildren()[name] = logger;583};584/**585 * There is a single global LogManager object that is used to maintain a set of586 * shared state about Loggers and log services. This is loosely based on the587 * java class java.util.logging.LogManager.588 */589goog.debug.LogManager = {};590/**591 * Map of logger names to logger objects592 *593 * @type {!Object}594 * @private595 */596goog.debug.LogManager.loggers_ = {};597/**598 * The root logger which is the root of the logger tree.599 * @type {goog.debug.Logger}600 * @private601 */602goog.debug.LogManager.rootLogger_ = null;603/**604 * Initialize the LogManager if not already initialized605 */606goog.debug.LogManager.initialize = function() {607  if (!goog.debug.LogManager.rootLogger_) {608    goog.debug.LogManager.rootLogger_ = new goog.debug.Logger('');609    goog.debug.LogManager.loggers_[''] = goog.debug.LogManager.rootLogger_;610    goog.debug.LogManager.rootLogger_.setLevel(goog.debug.Logger.Level.CONFIG);611  }612};613/**614 * Returns all the loggers615 * @return {!Object} Map of logger names to logger objects.616 */617goog.debug.LogManager.getLoggers = function() {618  return goog.debug.LogManager.loggers_;619};620/**621 * Returns the root of the logger tree namespace, the logger with the empty622 * string as its name623 *624 * @return {!goog.debug.Logger} The root logger.625 */626goog.debug.LogManager.getRoot = function() {627  goog.debug.LogManager.initialize();628  return /** @type {!goog.debug.Logger} */ (goog.debug.LogManager.rootLogger_);629};630/**631 * Method to find a named logger.632 *633 * @param {string} name A name for the logger. This should be a dot-separated634 * name and should normally be based on the package name or class name of the635 * subsystem, such as goog.net.BrowserChannel.636 * @return {!goog.debug.Logger} The named logger.637 */638goog.debug.LogManager.getLogger = function(name) {639  goog.debug.LogManager.initialize();640  var ret = goog.debug.LogManager.loggers_[name];641  return ret || goog.debug.LogManager.createLogger_(name);642};643/**644 * Creates a function that can be passed to goog.debug.catchErrors. The function645 * will log all reported errors using the given logger.646 * @param {goog.debug.Logger=} opt_logger The logger to log the errors to.647 *     Defaults to the root logger.648 * @return {function(Object)} The created function.649 */650goog.debug.LogManager.createFunctionForCatchErrors = function(opt_logger) {651  return function(info) {652    var logger = opt_logger || goog.debug.LogManager.getRoot();653    logger.severe('Error: ' + info.message + ' (' + info.fileName +654                  ' @ Line: ' + info.line + ')');655  };656};657/**658 * Creates the named logger. Will also create the parents of the named logger659 * if they don't yet exist.660 * @param {string} name The name of the logger.661 * @return {!goog.debug.Logger} The named logger.662 * @private663 */664goog.debug.LogManager.createLogger_ = function(name) {665  // find parent logger666  var logger = new goog.debug.Logger(name);667  if (goog.debug.Logger.ENABLE_HIERARCHY) {668    var lastDotIndex = name.lastIndexOf('.');669    var parentName = name.substr(0, lastDotIndex);670    var leafName = name.substr(lastDotIndex + 1);671    var parentLogger = goog.debug.LogManager.getLogger(parentName);672    // tell the parent about the child and the child about the parent673    parentLogger.addChild_(leafName, logger);674    logger.setParent_(parentLogger);675  }676  goog.debug.LogManager.loggers_[name] = logger;677  return logger;...logger.spec.js
Source:logger.spec.js  
1'use strict'2/*3 * adonis-framework4 *5 * (c) Harminder Virk <virk@adonisjs.com>6 *7 * For the full copyright and license information, please view the LICENSE8 * file that was distributed with this source code.9*/10const test = require('japa')11const path = require('path')12const fs = require('fs-extra')13const { ioc } = require('@adonisjs/fold')14const stdout = require('test-console').stdout15const { Config, Helpers } = require('@adonisjs/sink')16const FileDriver = require('../../src/Logger/Drivers').file17const ConsoleDriver = require('../../src/Logger/Drivers').console18const Logger = require('../../src/Logger')19const LoggerManager = require('../../src/Logger/Manager')20const LoggerFacade = require('../../src/Logger/Facade')21const sysLog = {22  emerg: 0,23  alert: 1,24  crit: 2,25  error: 3,26  warning: 4,27  notice: 5,28  info: 6,29  debug: 730}31test.group('Logger | File Driver', (group) => {32  group.beforeEach(() => {33    this.helpers = new Helpers(path.join(__dirname))34  })35  group.before((done) => {36    fs.ensureDir(path.join(__dirname, 'tmp'), done)37  })38  group.after((done) => {39    if (process.platform === 'win32') {40      return done()41    }42    fs.remove(path.join(__dirname, 'tmp'), done)43  })44  test('initiate logger with correct settings', (assert) => {45    const fileDriver = new FileDriver(this.helpers)46    fileDriver.setConfig({})47    assert.deepEqual(fileDriver.logger.levels, sysLog)48    assert.equal(fileDriver.logger.transports[0].dirname, path.join(__dirname, 'tmp'))49  })50  test('do not override filename when it is absolute path', (assert) => {51    const fileDriver = new FileDriver(this.helpers)52    fileDriver.setConfig({53      filename: path.join(__dirname, 'tmp', 'my.log')54    })55    assert.equal(fileDriver.config.filename, path.join(__dirname, 'tmp', 'my.log'))56  })57  test('log info to the file', (assert, done) => {58    const fileDriver = new FileDriver(this.helpers)59    fileDriver.setConfig({})60    fileDriver.logger.on('finish', () => {61      fs.readFile(fileDriver.config.filename, (error, contents) => {62        if (error) {63          return done(error)64        }65        contents = JSON.parse(contents)66        assert.equal(contents.message, 'hello')67        assert.equal(contents.level, 'info')68        done()69      })70    })71    fileDriver.log(6, 'hello')72    /**73     * Waiting for the transporter to write the file and then end74     * the logger75     */76    setTimeout(() => {77      fileDriver.logger.end()78    }, 100)79  }).timeout(3000)80  test('return active log level', (assert) => {81    const fileDriver = new FileDriver(this.helpers)82    fileDriver.setConfig({})83    assert.equal(fileDriver.level, 'info')84  })85  test('update log level', (assert) => {86    const fileDriver = new FileDriver(this.helpers)87    fileDriver.setConfig({})88    fileDriver.level = 'debug'89    assert.equal(fileDriver.level, 'debug')90  })91})92test.group('Logger | Console Driver', () => {93  test('initiate logger with correct settings', (assert) => {94    const consoleDriver = new ConsoleDriver()95    consoleDriver.setConfig({})96    assert.deepEqual(consoleDriver.logger.levels, sysLog)97  })98  test('log info to the console', (assert, done) => {99    const consoleDriver = new ConsoleDriver()100    consoleDriver.setConfig({})101    const inspect = stdout.inspect()102    consoleDriver.logger.on('finish', () => {103      inspect.restore()104      assert.include(inspect.output[0], 'hello')105      done()106    })107    consoleDriver.log(6, 'hello')108    consoleDriver.logger.end()109  }).timeout(3000)110  test('return active log level', (assert) => {111    const consoleDriver = new ConsoleDriver()112    consoleDriver.setConfig({})113    assert.equal(consoleDriver.level, 'info')114  })115  test('update log level', (assert) => {116    const consoleDriver = new ConsoleDriver()117    consoleDriver.setConfig({})118    consoleDriver.level = 'debug'119    assert.equal(consoleDriver.level, 'debug')120  })121})122test.group('Logger | Instance', (group) => {123  test('log info using defined driver', (assert, done) => {124    const consoleDriver = new ConsoleDriver()125    consoleDriver.setConfig({})126    const logger = new Logger(consoleDriver)127    const inspect = stdout.inspect()128    consoleDriver.logger.on('finish', () => {129      inspect.restore()130      assert.include(inspect.output[0], 'info')131      done()132    })133    logger.info('hello')134    consoleDriver.logger.end()135  })136  test('log warning using defined driver', (assert) => {137    const consoleDriver = new ConsoleDriver()138    consoleDriver.setConfig({})139    const logger = new Logger(consoleDriver)140    const inspect = stdout.inspect()141    logger.warning('hello')142    inspect.restore()143    assert.include(inspect.output[0], 'warning')144  })145  test('do not log level before the level defined on the driver', (assert) => {146    const consoleDriver = new ConsoleDriver()147    consoleDriver.setConfig({ level: 'info' })148    const logger = new Logger(consoleDriver)149    const inspect = stdout.inspect()150    logger.debug('hello')151    inspect.restore()152    assert.lengthOf(inspect.output, 0)153  })154  test('update log level', (assert) => {155    const consoleDriver = new ConsoleDriver()156    consoleDriver.setConfig({})157    const logger = new Logger(consoleDriver)158    logger.level = 'debug'159    const inspect = stdout.inspect()160    logger.debug('hello')161    inspect.restore()162    assert.include(inspect.output[0], 'debug')163  })164  test('get current log level', (assert) => {165    const consoleDriver = new ConsoleDriver()166    consoleDriver.setConfig({})167    const logger = new Logger(consoleDriver)168    assert.equal(logger.level, 'info')169  })170})171test.group('Logger | Manager', (group) => {172  group.before(() => {173    ioc.fake('Adonis/Src/Config', () => new Config())174    ioc.fake('Adonis/Src/Helpers', () => new Helpers(path.join(__dirname)))175  })176  test('extend logger by adding drivers', (assert) => {177    const myDriver = {}178    LoggerManager.extend('myDriver', myDriver)179    assert.deepEqual(LoggerManager._drivers, { myDriver })180  })181  test('throw error when trying to access invalid driver', (assert) => {182    const fn = () => LoggerManager.driver('foo')183    assert.throw(fn, 'E_INVALID_LOGGER_DRIVER: Logger driver foo does not exists')184  })185  test('return driver instance for a given driver', (assert) => {186    const consoleDriver = LoggerManager.driver('console')187    assert.instanceOf(consoleDriver, ConsoleDriver)188  })189})190test.group('Logger | Facade', (group) => {191  group.before(() => {192    ioc.fake('Adonis/Src/Config', () => new Config())193    ioc.fake('Adonis/Src/Helpers', () => new Helpers(path.join(__dirname)))194  })195  test('return logger instance with selected driver', (assert) => {196    const config = new Config()197    config.set('app.logger.file', {198      driver: 'file'199    })200    const logger = new LoggerFacade(config)201    assert.instanceOf(logger.transport('file'), Logger)202    assert.instanceOf(logger.transport('file').driver, FileDriver)203  })204  test('return logger instance with extended driver', (assert) => {205    const myDriver = {206      setConfig () {}207    }208    LoggerManager.extend('mydriver', myDriver)209    const config = new Config()210    config.set('app.logger.mydriver', {211      driver: 'mydriver'212    })213    const logger = new LoggerFacade(config)214    assert.instanceOf(logger.transport('mydriver'), Logger)215    assert.deepEqual(logger.transport('mydriver').driver, myDriver)216  })217  test('create singleton logger instances', (assert) => {218    const config = new Config()219    config.set('app.logger.file', {220      driver: 'file'221    })222    const logger = new LoggerFacade(config)223    logger.transport('file')224    assert.lengthOf(Object.keys(logger._loggerInstances), 1)225    logger.transport('file')226    assert.lengthOf(Object.keys(logger._loggerInstances), 1)227  })228  test('create different instance when transport is different', (assert) => {229    const config = new Config()230    config.set('app.logger.file', {231      driver: 'file'232    })233    config.set('app.logger.anotherFile', {234      driver: 'file'235    })236    const logger = new LoggerFacade(config)237    logger.transport('file')238    assert.lengthOf(Object.keys(logger._loggerInstances), 1)239    logger.transport('anotherFile')240    assert.lengthOf(Object.keys(logger._loggerInstances), 2)241  })242  test('proxy logger instance methods', (assert) => {243    const config = new Config()244    config.set('app.logger', {245      transport: 'console',246      console: {247        driver: 'console'248      }249    })250    const logger = new LoggerFacade(config)251    const inspect = stdout.inspect()252    logger.info('hello')253    inspect.restore()254    assert.include(inspect.output[0], 'hello')255  })256  test('throw exception when driver is invalid', (assert) => {257    const config = new Config()258    config.set('app.logger', {259      transport: 'console',260      console: {261        driver: 'foo'262      }263    })264    const logger = new LoggerFacade(config)265    const fn = () => logger.debug('')266    assert.throw(fn, 'E_INVALID_LOGGER_DRIVER: Logger driver foo does not exists')267  })268  test('throw exception when no transport is defined', (assert) => {269    const config = new Config()270    config.set('app.logger', {271    })272    const logger = new LoggerFacade(config)273    const fn = () => logger.debug('')274    assert.throw(fn, 'E_MISSING_CONFIG: logger.transport is not defined inside config/app.js file')275  })276  test('access loglevels from facade', (assert) => {277    const config = new Config()278    config.set('app.logger', {279      transport: 'file',280      file: {281        driver: 'file'282      }283    })284    const logger = new LoggerFacade(config)285    assert.deepEqual(logger.levels, {286      alert: 1,287      crit: 2,288      debug: 7,289      emerg: 0,290      error: 3,291      info: 6,292      notice: 5,293      warning: 4294    })295  })296  test('update log level from facade', (assert) => {297    const config = new Config()298    config.set('app.logger', {299      transport: 'console',300      console: {301        driver: 'console'302      }303    })304    const logger = new LoggerFacade(config)305    const inspect = stdout.inspect()306    logger.level = 'debug'307    logger.debug('foo')308    inspect.restore()309    assert.include(inspect.output[0], 'foo')310  })...test_logger.py
Source:test_logger.py  
...23        self.closed = True24class TestLogger(unittest.TestCase):25    def setUp(self):26        self.logger = Logger(register_console_logger=False)27    def test_write_to_one_logger(self):28        logger = LoggerMock(('Hello, world!', 'INFO'))29        self.logger.register_logger(logger)30        self.logger.write('Hello, world!', 'INFO')31        assert_true(logger.msg.timestamp.startswith('20'))32    def test_write_to_one_logger_with_trace_level(self):33        logger = LoggerMock(('expected message', 'TRACE'))34        self.logger.register_logger(logger)35        self.logger.write('expected message', 'TRACE')36        assert_true(hasattr(logger, 'msg'))37    def test_write_to_multiple_loggers(self):38        logger = LoggerMock(('Hello, world!', 'INFO'))39        logger2 = logger.copy()40        logger3 = logger.copy()41        self.logger.register_logger(logger, logger2, logger3)42        self.logger.message(MessageMock('', 'INFO', 'Hello, world!'))43        assert_true(logger.msg is logger2.msg)44        assert_true(logger.msg is logger.msg)45    def test_write_multiple_messages(self):46        msgs = [('0', 'ERROR'), ('1', 'WARN'), ('2', 'INFO'), ('3', 'DEBUG'), ('4', 'TRACE')]47        logger = LoggerMock(*msgs)48        self.logger.register_logger(logger)49        for msg, level in msgs:50            self.logger.write(msg, level)51            assert_equals(logger.msg.message, msg)52            assert_equals(logger.msg.level, level)53    def test_all_methods(self):54        logger = LoggerMock2(('Hello, world!', 'INFO'))55        self.logger.register_logger(logger)56        self.logger.output_file('name', 'path')57        self.logger.close()58        assert_equals(logger.output_file, ('name', 'path'))59        assert_true(logger.closed)60    def test_registered_logger_does_not_need_all_methods(self):61        logger = LoggerMock(('Hello, world!', 'INFO'))62        self.logger.register_logger(logger)63        self.logger.output_file('name', 'path')64        self.logger.close()65    def test_close_removes_registered_loggers(self):66        logger = LoggerMock(('Hello, world!', 'INFO'))67        logger2 = LoggerMock2(('Hello, world!', 'INFO'))68        self.logger.register_logger(logger, logger2)69        self.logger.close()70        assert_equals(self.logger._loggers.all_loggers(), [])71    def test_registering_file_logger_with_none_path_does_nothing(self):72        self.logger.register_file_logger('None')73        assert_equals(self.logger._loggers.all_loggers(), [])74    def test_cached_messages_are_given_to_registered_writers(self):75        self.logger.write('This is a cached message', 'INFO')76        self.logger.write('Another cached message', 'TRACE')77        logger = LoggerMock(('This is a cached message', 'INFO'),78                            ('Another cached message', 'TRACE'))79        self.logger.register_logger(logger)80        assert_equals(logger.msg.message, 'Another cached message')81    def test_message_cache_can_be_turned_off(self):82        self.logger.disable_message_cache()83        self.logger.write('This message is not cached', 'INFO')84        logger = LoggerMock(('', ''))85        self.logger.register_logger(logger)86        assert_false(hasattr(logger, 'msg'))87    def test_start_and_end_suite_test_and_keyword(self):88        class MyLogger:89            def start_suite(self, suite): self.started_suite = suite90            def end_suite(self, suite): self.ended_suite = suite91            def start_test(self, test): self.started_test = test92            def end_test(self, test): self.ended_test = test93            def start_keyword(self, keyword): self.started_keyword = keyword94            def end_keyword(self, keyword): self.ended_keyword = keyword95        logger = MyLogger()96        self.logger.register_logger(logger)97        for name in 'suite', 'test', 'keyword':98            for stend in 'start', 'end':99                getattr(self.logger, stend + '_' + name)(name)100                assert_equals(getattr(logger, stend + 'ed_' + name), name)101    def test_console_logger_is_automatically_registered(self):102        logger = Logger()103        assert_true(logger._loggers.all_loggers()[0].start_suite.im_class is CommandLineMonitor)104    def test_loggercollection_is_iterable(self):105        logger = Logger()106        for log in logger._loggers:107            assert_true(log)108    def test_logger_is_iterable(self):109        logger = Logger()110        for log in logger:111            assert_true(log)112        assert_equals(list(logger), list(logger._loggers))113    def test_automatic_console_logger_can_be_disabled(self):114        logger = Logger()115        logger.unregister_console_logger()116        assert_equals(logger._loggers.all_loggers(), [])117    def test_automatic_console_logger_can_be_disabled_after_registering_logger(self):118        logger = Logger()119        mock = LoggerMock()120        logger.register_logger(mock)121        logger.unregister_console_logger()122        self._number_of_registered_loggers_should_be(1, logger)123        assert_true(logger._loggers.all_loggers()[0].message.im_class is LoggerMock)124    def test_disabling_automatic_logger_multiple_times_has_no_effect(self):125        logger = Logger()126        logger.unregister_console_logger()127        self._number_of_registered_loggers_should_be(0, logger)128        logger.unregister_console_logger()129        logger.unregister_console_logger()130        self._number_of_registered_loggers_should_be(0, logger)131        logger.register_logger(LoggerMock())132        logger.unregister_console_logger()133        self._number_of_registered_loggers_should_be(1, logger)134    def test_registering_console_logger_disables_automatic_console_logger(self):135        logger = Logger()136        logger.register_console_logger(width=42)137        self._number_of_registered_loggers_should_be(1, logger)138        assert_equals(logger._loggers.all_loggers()[0].start_suite.im_self._writer._width, 42)139    def test_unregister_logger(self):140        logger1, logger2, logger3 = LoggerMock(), LoggerMock(), LoggerMock()141        self.logger.register_logger(logger1, logger2, logger3)142        self.logger.unregister_logger(logger2)143        self._number_of_registered_loggers_should_be(2)144        self.logger.unregister_logger(logger3, logger1)145        self._number_of_registered_loggers_should_be(0)146    def test_unregistering_non_registered_logger_is_ok(self):147        logger1, logger2 = LoggerMock(), LoggerMock()148        self.logger.register_logger(logger1)149        self.logger.unregister_logger(logger2)150        self.logger.unregister_logger(None)151    def test_registering_context_changing_logger(self):152        self.logger.register_context_changing_logger(LoggerMock())153        self._number_of_registered_loggers_should_be(1)154    def test_messages_to_context_chagning_loggers(self):155        log = LoggerMock(('msg', 'INFO'))156        self.logger.register_context_changing_logger(log)157        self.logger.write('msg', 'INFO')158        assert_true(log.msg is not None)159    def test_start_methods_are_called_first_for_context_changing_loggers(self):160        class FirstLogger:161            def start_suite(self, suite): self.suite = suite162            def start_test(self, test): self.test = test163            def start_keyword(self, kw): self.kw = kw164        class SecondLogger:165            def __init__(self, logger): self._reference = logger166            def start_suite(self, suite): assert_equals(suite, self._reference.suite)167            def start_test(self, test): assert_equals(test, self._reference.test)168            def start_keyword(self, kw): assert_equals(kw, self._reference.kw)169        log1 = FirstLogger()170        log2 = SecondLogger(log1)171        self.logger.register_logger(log2)172        self.logger.register_context_changing_logger(log1)173        self.logger.start_suite('Suite')174        self.logger.start_test('Test')175        self.logger.start_keyword('Keyword')176    def test_end_methods_are_called_last_for_context_changing_loggers(self):177        class FirstLogger:178            def end_suite(self, suite): self.suite = suite179            def end_test(self, test): self.test = test180            def end_keyword(self, kw): self.kw = kw181        class SecondLogger:182            def __init__(self, logger): self._reference = logger183            def end_suite(self, suite): self.suite = suite; assert_equals(suite, self._reference.suite)184            def end_test(self, test): assert_equals(test, self._reference.test)185            def end_keyword(self, kw): assert_equals(kw, self._reference.kw)186        log1 = FirstLogger()187        log2 = SecondLogger(log1)188        self.logger.register_logger(log1)189        self.logger.register_context_changing_logger(log2)190        self.logger.end_suite('Suite')191        self.logger.end_test('Test')192        self.logger.end_keyword('Keyword')193        assert_true(log2.suite is not None)194    def _number_of_registered_loggers_should_be(self, number, logger=None):195        logger = logger or self.logger196        assert_equals(len(logger._loggers.all_loggers()), number)197if __name__ == "__main__":...cloudinaryCon.js
Source:cloudinaryCon.js  
1/**2 * #k_infinityIII@Echwood3 *4 * cloudinaryCon:5 *  sets up enviroment to upload images and videos6 *7 * Fucntions:8 *9 *10 */11// Config settings12import config from '../utils/config'13import schoolEvent from '../../interfaces/Events/schoolEvents'14import winstonLogger from '../utils/winstonLogger'15import cloudinary from 'cloudinary'16// const cloudinary = require('cloudinary').v217cloudinary.config({ 18    cloud_name: config.cloudinaryName,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               19    api_key: config.cloudinaryAPIKey, 20    api_secret: config.cloudinarySecret 21})22const cloudinaryCon = {23    async uploadSchoolLogo(Logo, Name, schoolID){24        let res = null 25        const schoolID0 = schoolID + "Logo"26        winstonLogger.info("CLOUDINARY")27        winstonLogger.info(JSON.stringify(cloudinary.v2,null,4))28        await cloudinary.v2.uploader.upload(29            Logo, 30            {31                folder: Name,32                public_id: schoolID0,33                overwrite: true,34                invalidate: true,35                width: 810, height: 456, crop: "fill"36        }).37        then((result) => {38            res = result39        }).40        catch((e) => {41            winstonLogger.error('Error uploading  Image')42            winstonLogger.error(JSON.stringify(e,null,4))43            return res = false44        })45        // Emit event for LogoPersistence46        try {47            48            winstonLogger.info('Upload Result')49            winstonLogger.info(JSON.stringify(res.url, null,4))50            51            if(res !== null && res !== false){52            }                53                const schoolName = Name54                const logoURL = res.url55                winstonLogger.info('EVENT PARAMETERS')56                winstonLogger.info(Name)57                winstonLogger.info(schoolID)58                winstonLogger.info(res.url)59                // fire Events then send payload60                schoolEvent.61                emit('school-logoUploaded',62                    {// send params63                    schoolName,64                    schoolID, 65                    logoURL66                })67                return res = true68        } catch (e) {69        70            winstonLogger.error('Error emitting event')71            winstonLogger.error(JSON.stringify(e,null,4))72            return res = false73        }74        // Check if the db url was updated else persist the picture to local storage[serialise] and try again later75        76        return res77    }, 78    async uploadSchoolImages(Images){79        cloudinary.v2.uploader.upload(80            Image,81            {82            },83            (e,res) => {84                if( e != null ){85                    86                    winstonLogger.error(e)87                }88                winstonLogger.info(res)89                return res90            })91    },92    //uploadNotificationImages93    async uploadNotificationImages(noteTitle,notificationID,notificationImage, Name, schoolID){94        let res = null 95        winstonLogger.info("CLOUDINARY")96        winstonLogger.info(noteTitle)97        winstonLogger.info(notificationID)98        winstonLogger.info(notificationImage)99        winstonLogger.info(schoolID)100        winstonLogger.info(Name)101    102        await cloudinary.v2.uploader.upload(103            notificationImage, 104            {105                folder: Name+"/"+"notifications",106                public_id: noteTitle,107                overwrite: true,108                invalidate: true,109                // width: 810, height: 456, crop: "fill"110        }).111        then((result) => {112            winstonLogger.info('UPLOADING...')113            winstonLogger.info(JSON.stringify(result,null,4))114            res = result115        }).116        catch((e) => {117            winstonLogger.error('Error uploading  Image')118            winstonLogger.error(JSON.stringify(e,null,4))119            return res = false120        })121        // Emit event for Persistence122        try {123            124            winstonLogger.info('Upload Result')125            winstonLogger.info(JSON.stringify(res.url, null,4))126            127            if(res !== null && res !== false){128            }                129                const schoolName = Name130                const notificationURL = res.url131                winstonLogger.info('EVENT PARAMETERS')132                winstonLogger.info(Name)133                winstonLogger.info(schoolID)134                winstonLogger.info(res.url)135                // fire Events then send payload136                schoolEvent.137                emit('school-notificationImageUploaded',138                    {// send params139                    schoolName,140                    schoolID,141                    notificationID, 142                    notificationURL143                })144                return res = true145        } catch (e) {146        147            winstonLogger.error('Error emitting event')148            winstonLogger.error(JSON.stringify(e,null,4))149            return res = false150        }151        // Check if the db url was updated else persist the picture to local storage[serialise] and try again later152        return res153    },154    //155    async uploadLectureNote(schoolName,schoolID,subjectName,lectureNoteTitle,lectureNoteData,teacherID,classAlias){156        let res = null 157        winstonLogger.info("CLOUDINARY")158        winstonLogger.info(schoolName)159        winstonLogger.info(schoolID)160        winistsonLogger.info(subjectName)161        winstonLogger.info(lectureNoteTitle)162        winstonLogger.info(lectureNoteData)163        winstonLogger.info(teacherID)164        winstonLogger.info(classAlias)165        166        await cloudinary.v2.uploader.upload(// PDF167            lectureNoteData, 168            {169                folder: schoolName+"/"+classAlias+"/"+subjectName,170                public_id: lectureNoteTitle,171                overwrite: true,172                invalidate: true,173                // width: 810, height: 456, crop: "fill"174        }).175        then((result) => {176            winstonLogger.info('UPLOADING...')177            winstonLogger.info(JSON.stringify(result,null,4))178            res = result179        }).180        catch((e) => {181            winstonLogger.error('Error uploading  Image')182            winstonLogger.error(JSON.stringify(e,null,4))183            return res = false184        })185        // Emit event for Persistence186        try {187            188            winstonLogger.info('Upload Result')189            winstonLogger.info(JSON.stringify(res.url, null,4))190            191            if(res){192          193                const lectureNoteURL = res.url194                winstonLogger.info('EVENT PARAMETERS')195                winstonLogger.info(schoolName)196                winstonLogger.info(schoolID)197                winstonLogger.info(lectureNoteTitle)198                winstonLogger.info(lectureNoteData)199                winstonLogger.info(teacherID)200                winstonLogger.info(classAlias)201                // fire Events then send payload202                schoolEvent.203                emit('school-lectureNoteUpdloaded',204                    {// send params205                    schoolName,206                    schoolID,207                    classAlias,208                    teacherID,209                    subjectName,210                    lectureNoteTitle,211                    lectureNoteUrl212                })213                return res = true214            }215        } catch (e) {216        217            winstonLogger.error('Error emitting event')218            winstonLogger.error(JSON.stringify(e,null,4))219            return res = false220        }221        // Check if the db url was updated else persist the picture to local storage[serialise] and try again later222        return res223    }224}...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
