浏览代码

refactoring logging logic

afrokick 6 年之前
父节点
当前提交
815199e010
共有 9 个文件被更改,包括 181 次插入178 次删除
  1. 3 2
      lib/api.ts
  2. 7 5
      lib/dataconnection.ts
  3. 66 0
      lib/logger.ts
  4. 4 3
      lib/mediaconnection.ts
  5. 30 29
      lib/negotiator.ts
  6. 21 19
      lib/peer.ts
  7. 5 5
      lib/socket.ts
  8. 0 115
      lib/util.ts
  9. 45 0
      test/logger.ts

+ 3 - 2
lib/api.ts

@@ -1,4 +1,5 @@
 import { util } from "./util";
+import logger from "./logger";
 
 export class API {
   constructor(private readonly _options: any) { }
@@ -33,7 +34,7 @@ export class API {
 
       return response.text();
     } catch (error) {
-      util.error("Error retrieving ID", error);
+      logger.error("Error retrieving ID", error);
 
       let pathError = "";
 
@@ -81,7 +82,7 @@ export class API {
 
       return response.json();
     } catch (error) {
-      util.error("Error retrieving list peers", error);
+      logger.error("Error retrieving list peers", error);
 
       throw new Error("Could not get list peers from the server." + error);
     }

+ 7 - 5
lib/dataconnection.ts

@@ -1,6 +1,7 @@
+import { Reliable } from "reliable";
 import { util } from "./util";
+import logger, { LogLevel } from "./logger";
 import Negotiator from "./negotiator";
-import { Reliable } from "reliable";
 import {
   ConnectionType,
   ConnectionEventType,
@@ -74,14 +75,15 @@ export class DataConnection extends BaseConnection {
     }
 
     this.dataChannel.onopen = () => {
-      util.log("Data channel connection success");
+      logger.log("Data channel connection success");
       this._open = true;
       this.emit(ConnectionEventType.Open);
     };
 
     // Use the Reliable shim for non Firefox browsers
     if (!util.supports.sctp && this.reliable) {
-      this._reliable = new Reliable(this.dataChannel, util.debug);
+      const isLoggingEnable = logger.logLevel > LogLevel.Disabled;
+      this._reliable = new Reliable(this.dataChannel, isLoggingEnable);
     }
 
     if (this._reliable) {
@@ -94,7 +96,7 @@ export class DataConnection extends BaseConnection {
       };
     }
     this.dataChannel.onclose = () => {
-      util.log("DataChannel closed for:", this.peer);
+      logger.log("DataChannel closed for:", this.peer);
       this.close();
     };
   }
@@ -302,7 +304,7 @@ export class DataConnection extends BaseConnection {
         Negotiator.handleCandidate(this, payload.candidate);
         break;
       default:
-        util.warn(
+        logger.warn(
           "Unrecognized message type:",
           message.type,
           "from peer:",

+ 66 - 0
lib/logger.ts

@@ -0,0 +1,66 @@
+const LOG_PREFIX = 'PeerJS: ';
+
+/*
+Prints log messages depending on the debug level passed in. Defaults to 0.
+0  Prints no logs.
+1  Prints only errors.
+2  Prints errors and warnings.
+3  Prints all logs.
+*/
+export enum LogLevel {
+    Disabled,
+    Errors,
+    Warnings,
+    All
+}
+
+class Logger {
+    private _logLevel = LogLevel.Disabled;
+
+    get logLevel(): LogLevel { return this._logLevel; }
+
+    set logLevel(logLevel: LogLevel) { this._logLevel = logLevel; }
+
+    log(...args) {
+        if (this._logLevel >= LogLevel.All) {
+            this._print(LogLevel.All, ...args);
+        }
+    }
+
+    warn(...args) {
+        if (this._logLevel >= LogLevel.Warnings) {
+            this._print(LogLevel.Warnings, ...args);
+        }
+    }
+
+    error(...args) {
+        if (this._logLevel >= LogLevel.Errors) {
+            this._print(LogLevel.Errors, ...args);
+        }
+    }
+
+    setLogFunction(fn: (logLevel: LogLevel, ..._) => void): void {
+        this._print = fn;
+    }
+
+    private _print(logLevel: LogLevel, ...rest): void {
+        const copy = [LOG_PREFIX, ...rest];
+
+        for (let i in copy) {
+            if (copy[i] instanceof Error) {
+                copy[i] = "(" + copy[i].name + ") " + copy[i].message;
+
+            }
+        }
+
+        if (logLevel >= LogLevel.All) {
+            console.log(...copy);
+        } else if (logLevel >= LogLevel.Warnings) {
+            console.warn("WARNING", ...copy);
+        } else if (logLevel >= LogLevel.Errors) {
+            console.error("ERROR", ...copy);
+        }
+    }
+}
+
+export default new Logger();

+ 4 - 3
lib/mediaconnection.ts

@@ -1,4 +1,5 @@
 import { util } from "./util";
+import logger from "./logger";
 import Negotiator from "./negotiator";
 import { ConnectionType, ConnectionEventType, ServerMessageType } from "./enums";
 import { Peer } from "./peer";
@@ -38,7 +39,7 @@ export class MediaConnection extends BaseConnection {
   }
 
   addStream(remoteStream) {
-    util.log("Receiving stream", remoteStream);
+    logger.log("Receiving stream", remoteStream);
 
     this._remoteStream = remoteStream;
     super.emit(ConnectionEventType.Stream, remoteStream); // Should we call this `open`?
@@ -58,14 +59,14 @@ export class MediaConnection extends BaseConnection {
         Negotiator.handleCandidate(this, payload.candidate);
         break;
       default:
-        util.warn(`Unrecognized message type:${type} from peer:${this.peer}`);
+        logger.warn(`Unrecognized message type:${type} from peer:${this.peer}`);
         break;
     }
   }
 
   answer(stream: MediaStream): void {
     if (this._localStream) {
-      util.warn(
+      logger.warn(
         "Local stream already exists on this MediaConnection. Are you answering a call twice?"
       );
       return;

+ 30 - 29
lib/negotiator.ts

@@ -1,10 +1,11 @@
+import * as Reliable from "reliable";
 import { util } from "./util";
+import logger from "./logger";
 import {
   RTCPeerConnection,
   RTCSessionDescription,
   RTCIceCandidate
 } from "./adapter";
-import * as Reliable from "reliable";
 import { MediaConnection } from "./mediaconnection";
 import { DataConnection } from "./dataconnection";
 import { ConnectionType, PeerErrorType, ConnectionEventType, ServerMessageType } from "./enums";
@@ -63,7 +64,7 @@ class Negotiator {
     options: any
   ): RTCPeerConnection {
     if (!this.pcs[connection.type]) {
-      util.error(
+      logger.error(
         connection.type +
         " is not a valid connection type. Maybe you overrode the `type` property somewhere."
       );
@@ -91,7 +92,7 @@ class Negotiator {
 
   /** Start a PC. */
   private _startPeerConnection(connection: BaseConnection): RTCPeerConnection {
-    util.log("Creating RTCPeerConnection.");
+    logger.log("Creating RTCPeerConnection.");
 
     const id = this._idPrefix + util.randomToken();
     let optional = {};
@@ -126,11 +127,11 @@ class Negotiator {
     const provider = connection.provider;
 
     // ICE CANDIDATES.
-    util.log("Listening for ICE candidates.");
+    logger.log("Listening for ICE candidates.");
 
     peerConnection.onicecandidate = (evt) => {
       if (evt.candidate) {
-        util.log("Received ICE candidates for:", peerId);
+        logger.log("Received ICE candidates for:", peerId);
         provider.socket.send({
           type: ServerMessageType.Candidate,
           payload: {
@@ -146,7 +147,7 @@ class Negotiator {
     peerConnection.oniceconnectionstatechange = () => {
       switch (peerConnection.iceConnectionState) {
         case "failed":
-          util.log(
+          logger.log(
             "iceConnectionState is failed, closing connections to " +
             peerId
           );
@@ -157,7 +158,7 @@ class Negotiator {
           connection.close();
           break;
         case "closed":
-          util.log(
+          logger.log(
             "iceConnectionState is closed, closing connections to " +
             peerId
           );
@@ -168,7 +169,7 @@ class Negotiator {
           connection.close();
           break;
         case "disconnected":
-          util.log(
+          logger.log(
             "iceConnectionState is disconnected, closing connections to " +
             peerId
           );
@@ -184,11 +185,11 @@ class Negotiator {
     peerConnection.onicechange = peerConnection.oniceconnectionstatechange;
 
     // DATACONNECTION.
-    util.log("Listening for data channel");
+    logger.log("Listening for data channel");
     // Fired between offer and answer, so options should already be saved
     // in the options hash.
     peerConnection.ondatachannel = (evt) => {
-      util.log("Received data channel");
+      logger.log("Received data channel");
 
       const dataChannel = evt.channel;
       const connection = <DataConnection>(
@@ -199,10 +200,10 @@ class Negotiator {
     };
 
     // MEDIACONNECTION.
-    util.log("Listening for remote stream");
+    logger.log("Listening for remote stream");
 
     peerConnection.ontrack = (evt) => {
-      util.log("Received remote stream");
+      logger.log("Received remote stream");
 
       const stream = evt.streams[0];
       const connection = provider.getConnection(peerId, connectionId);
@@ -216,7 +217,7 @@ class Negotiator {
   }
 
   cleanup(connection: BaseConnection): void {
-    util.log("Cleaning up PeerConnection to " + connection.peer);
+    logger.log("Cleaning up PeerConnection to " + connection.peer);
 
     const peerConnection = connection.peerConnection;
 
@@ -249,7 +250,7 @@ class Negotiator {
         connection.options.constraints
       );
 
-      util.log("Created offer.");
+      logger.log("Created offer.");
 
       if (!util.supports.sctp && connection.type === ConnectionType.Data) {
         const dataConnection = <DataConnection>connection;
@@ -265,7 +266,7 @@ class Negotiator {
       try {
         await peerConnection.setLocalDescription(offer);
 
-        util.log("Set localDescription:", offer, `for:${connection.peer}`);
+        logger.log("Set localDescription:", offer, `for:${connection.peer}`);
 
         let payload: any = {
           sdp: offer,
@@ -298,12 +299,12 @@ class Negotiator {
           "OperationError: Failed to set local offer sdp: Called in wrong state: kHaveRemoteOffer"
         ) {
           connection.provider.emitError(PeerErrorType.WebRTC, err);
-          util.log("Failed to setLocalDescription, ", err);
+          logger.log("Failed to setLocalDescription, ", err);
         }
       }
     } catch (err_1) {
       connection.provider.emitError(PeerErrorType.WebRTC, err_1);
-      util.log("Failed to createOffer, ", err_1);
+      logger.log("Failed to createOffer, ", err_1);
     }
   }
 
@@ -312,7 +313,7 @@ class Negotiator {
 
     try {
       const answer = await peerConnection.createAnswer();
-      util.log("Created answer.");
+      logger.log("Created answer.");
 
       if (!util.supports.sctp && connection.type === ConnectionType.Data) {
         const dataConnection = <DataConnection>connection;
@@ -324,7 +325,7 @@ class Negotiator {
       try {
         await peerConnection.setLocalDescription(answer);
 
-        util.log(`Set localDescription:`, answer, `for:${connection.peer}`);
+        logger.log(`Set localDescription:`, answer, `for:${connection.peer}`);
 
         connection.provider.socket.send({
           type: ServerMessageType.Answer,
@@ -338,11 +339,11 @@ class Negotiator {
         });
       } catch (err) {
         connection.provider.emitError(PeerErrorType.WebRTC, err);
-        util.log("Failed to setLocalDescription, ", err);
+        logger.log("Failed to setLocalDescription, ", err);
       }
     } catch (err_1) {
       connection.provider.emitError(PeerErrorType.WebRTC, err_1);
-      util.log("Failed to create answer, ", err_1);
+      logger.log("Failed to create answer, ", err_1);
     }
   }
 
@@ -355,19 +356,19 @@ class Negotiator {
     sdp = new RTCSessionDescription(sdp);
     const peerConnection = connection.peerConnection;
 
-    util.log("Setting remote description", sdp);
+    logger.log("Setting remote description", sdp);
 
     const self = this;
 
     try {
       await peerConnection.setRemoteDescription(sdp);
-      util.log(`Set remoteDescription:${type} for:${connection.peer}`);
+      logger.log(`Set remoteDescription:${type} for:${connection.peer}`);
       if (type === "OFFER") {
         await self._makeAnswer(connection);
       }
     } catch (err) {
       connection.provider.emitError(PeerErrorType.WebRTC, err);
-      util.log("Failed to setRemoteDescription, ", err);
+      logger.log("Failed to setRemoteDescription, ", err);
     }
   }
 
@@ -383,10 +384,10 @@ class Negotiator {
           candidate: candidate
         })
       );
-      util.log(`Added ICE candidate for:${connection.peer}`);
+      logger.log(`Added ICE candidate for:${connection.peer}`);
     } catch (err) {
       connection.provider.emitError(PeerErrorType.WebRTC, err);
-      util.log("Failed to handleCandidate, ", err);
+      logger.log("Failed to handleCandidate, ", err);
     }
   }
 
@@ -394,10 +395,10 @@ class Negotiator {
     stream: MediaStream,
     peerConnection: RTCPeerConnection
   ): void {
-    util.log(`add tracks from stream ${stream.id} to peer connection`);
+    logger.log(`add tracks from stream ${stream.id} to peer connection`);
 
     if (!peerConnection.addTrack) {
-      return util.error(
+      return logger.error(
         `Your browser does't support RTCPeerConnection#addTrack. Ignored.`
       );
     }
@@ -411,7 +412,7 @@ class Negotiator {
     stream: MediaStream,
     mediaConnection: MediaConnection
   ): void {
-    util.log(
+    logger.log(
       `add stream ${stream.id} to media connection ${
       mediaConnection.connectionId
       }`

+ 21 - 19
lib/peer.ts

@@ -1,5 +1,6 @@
-import { util } from "./util";
 import { EventEmitter } from "eventemitter3";
+import { util } from "./util";
+import logger, { LogLevel } from "./logger";
 import { Socket } from "./socket";
 import { MediaConnection } from "./mediaconnection";
 import { DataConnection } from "./dataconnection";
@@ -12,11 +13,11 @@ import {
 } from "./enums";
 import { BaseConnection } from "./baseconnection";
 import { ServerMessage } from "./servermessage";
-import { PeerConnectOption, PeerJSOption } from "..";
 import { API } from "./api";
+import { PeerConnectOption, PeerJSOption } from "..";
 
 class PeerOptions implements PeerJSOption {
-  debug?: number; // 1: Errors, 2: Warnings, 3: All logs
+  debug?: LogLevel; // 1: Errors, 2: Warnings, 3: All logs
   host?: string;
   port?: number;
   path?: string;
@@ -24,7 +25,7 @@ class PeerOptions implements PeerJSOption {
   token?: string;
   config?: any;
   secure?: boolean;
-  logFunction?: any;
+  logFunction?: (logLevel: LogLevel, ...rest) => void;
 }
 
 /**
@@ -128,9 +129,10 @@ export class Peer extends EventEmitter {
     }
     // Set a custom log function if present
     if (options.logFunction) {
-      util.setLogFunction(options.logFunction);
+      logger.setLogFunction(options.logFunction);
     }
-    util.setLogLevel(String(options.debug));
+
+    logger.logLevel = options.debug;
 
     // Sanity checks
     // Ensure WebRTC supported
@@ -229,7 +231,7 @@ export class Peer extends EventEmitter {
         );
         break;
       case ServerMessageType.Leave: // Another peer has closed its connection to this peer.
-        util.log("Received leave message from", peerId);
+        logger.log("Received leave message from", peerId);
         this._cleanupPeer(peerId);
         this._connections.delete(peerId);
         break;
@@ -246,7 +248,7 @@ export class Peer extends EventEmitter {
 
         if (connection) {
           connection.close();
-          util.warn("Offer received for existing Connection ID:", connectionId);
+          logger.warn("Offer received for existing Connection ID:", connectionId);
         }
 
         // Create a new connection.
@@ -270,7 +272,7 @@ export class Peer extends EventEmitter {
           this._addConnection(peerId, connection);
           this.emit(PeerEventType.Connection, connection);
         } else {
-          util.warn("Received malformed connection type:", payload.type);
+          logger.warn("Received malformed connection type:", payload.type);
           return;
         }
 
@@ -284,7 +286,7 @@ export class Peer extends EventEmitter {
       }
       default: {
         if (!payload) {
-          util.warn(
+          logger.warn(
             `You received a malformed message from ${peerId} of type ${type}`
           );
           return;
@@ -300,7 +302,7 @@ export class Peer extends EventEmitter {
           // Store for possible later use
           this._storeMessage(connectionId, message);
         } else {
-          util.warn("You received an unrecognized message:", message);
+          logger.warn("You received an unrecognized message:", message);
         }
         break;
       }
@@ -335,7 +337,7 @@ export class Peer extends EventEmitter {
    */
   connect(peer: string, options?: PeerConnectOption): DataConnection {
     if (this.disconnected) {
-      util.warn(
+      logger.warn(
         "You cannot connect to a new Peer because you called " +
         ".disconnect() on this Peer and ended your connection with the " +
         "server. You can create a new Peer to reconnect, or call reconnect " +
@@ -359,7 +361,7 @@ export class Peer extends EventEmitter {
    */
   call(peer: string, stream: MediaStream, options: any = {}): MediaConnection {
     if (this.disconnected) {
-      util.warn(
+      logger.warn(
         "You cannot connect to a new Peer because you called " +
         ".disconnect() on this Peer and ended your connection with the " +
         "server. You can create a new Peer to reconnect."
@@ -372,7 +374,7 @@ export class Peer extends EventEmitter {
     }
 
     if (!stream) {
-      util.error(
+      logger.error(
         "To call a peer, you must provide a stream from your browser's `getUserMedia`."
       );
       return;
@@ -387,7 +389,7 @@ export class Peer extends EventEmitter {
 
   /** Add a data/media connection to this peer. */
   private _addConnection(peerId: string, connection: BaseConnection): void {
-    util.log(
+    logger.log(
       `add connection ${connection.type}:${connection.connectionId}
        to peerId:${peerId}`
     );
@@ -426,7 +428,7 @@ export class Peer extends EventEmitter {
    * it retains its disconnected state and its existing connections.
    */
   private _abort(type: PeerErrorType, message): void {
-    util.error("Aborting!");
+    logger.error("Aborting!");
 
     if (!this._lastServerId) {
       this.destroy();
@@ -439,7 +441,7 @@ export class Peer extends EventEmitter {
 
   /** Emits a typed error message. */
   emitError(type: PeerErrorType, err): void {
-    util.error("Error:", err);
+    logger.error("Error:", err);
 
     if (typeof err === "string") {
       err = new Error(err);
@@ -510,7 +512,7 @@ export class Peer extends EventEmitter {
   /** Attempts to reconnect with the same ID. */
   reconnect(): void {
     if (this.disconnected && !this.destroyed) {
-      util.log(
+      logger.log(
         "Attempting reconnection to server with ID " + this._lastServerId
       );
       this._disconnected = false;
@@ -522,7 +524,7 @@ export class Peer extends EventEmitter {
       );
     } else if (!this.disconnected && !this.open) {
       // Do nothing. We're still connecting the first time.
-      util.error(
+      logger.error(
         "In a hurry? We're still trying to make the initial connection!"
       );
     } else {

+ 5 - 5
lib/socket.ts

@@ -1,5 +1,5 @@
-import { util } from "./util";
 import { EventEmitter } from "eventemitter3";
+import logger from "./logger";
 import { SocketEventType, ServerMessageType } from "./enums";
 
 /**
@@ -53,7 +53,7 @@ export class Socket extends EventEmitter {
       try {
         data = JSON.parse(event.data);
       } catch (e) {
-        util.log("Invalid server message", event.data);
+        logger.log("Invalid server message", event.data);
         return;
       }
 
@@ -61,7 +61,7 @@ export class Socket extends EventEmitter {
     };
 
     this._socket.onclose = (event) => {
-      util.log("Socket closed.", event);;
+      logger.log("Socket closed.", event);;
 
       this._disconnected = true;
       clearTimeout(this._wsPingTimer);
@@ -76,7 +76,7 @@ export class Socket extends EventEmitter {
 
       this._sendQueuedMessages();
 
-      util.log("Socket open");
+      logger.log("Socket open");
 
       this._scheduleHeartbeat();
     };
@@ -88,7 +88,7 @@ export class Socket extends EventEmitter {
 
   private _sendHeartbeat(): void {
     if (!this._wsOpen()) {
-      util.log(`Cannot send heartbeat, because socket closed`);
+      logger.log(`Cannot send heartbeat, because socket closed`);
       return;
     }
 

+ 0 - 115
lib/util.ts

@@ -6,20 +6,6 @@ const DEFAULT_CONFIG = {
   sdpSemantics: "unified-plan"
 };
 
-/*
-Prints log messages depending on the debug level passed in. Defaults to 0.
-0  Prints no logs.
-1  Prints only errors.
-2  Prints errors and warnings.
-3  Prints all logs.
-*/
-export enum DebugLevel {
-  Disabled,
-  Errors,
-  Warnings,
-  All
-}
-
 export class util {
   static noop(): void { }
 
@@ -30,65 +16,6 @@ export class util {
   static readonly chunkedBrowsers = { Chrome: 1 };
   static readonly chunkedMTU = 16300; // The original 60000 bytes setting does not work when sending data from Firefox to Chrome, which is "cut off" after 16384 bytes and delivered individually.
 
-  // Logging logic
-  static readonly debug = false;
-  static logLevel = DebugLevel.Disabled;
-
-  static setLogLevel(level: string): void {
-    const debugLevel = parseInt(level, 10);
-
-    if (!isNaN(parseInt(level, 10))) {
-      util.logLevel = debugLevel;
-    } else {
-      // If they are using truthy/falsy values for debug
-      util.logLevel = level ? DebugLevel.All : DebugLevel.Disabled;
-    }
-    util.log = util.warn = util.error = util.noop;
-    if (util.logLevel > DebugLevel.Disabled) {
-      util.error = util._printWith("ERROR");
-    }
-    if (util.logLevel > DebugLevel.Errors) {
-      util.warn = util._printWith("WARNING");
-    }
-    if (util.logLevel > DebugLevel.Warnings) {
-      util.log = util._print;
-    }
-  }
-
-  static setLogFunction(fn): void {
-    if (fn.constructor !== Function) {
-      util.warn(
-        "The log function you passed in is not a function. Defaulting to regular logs."
-      );
-    } else {
-      util._print = fn;
-    }
-  }
-
-  private static _printWith(prefix) {
-    return function () {
-      const copy = Array.prototype.slice.call(arguments);
-      copy.unshift(prefix);
-      util._print.apply(util, copy);
-    };
-  }
-
-  private static _print(...rest): void {
-    let err = false;
-    const copy = [...rest];
-
-    copy.unshift("PeerJS: ");
-
-    for (let i in copy) {
-      if (copy[i] instanceof Error) {
-        copy[i] = "(" + copy[i].name + ") " + copy[i].message;
-        err = true;
-      }
-    }
-
-    err ? console.error.apply(console, copy) : console.log.apply(console, copy);
-  }
-
   // Returns browser-agnostic default config
   static readonly defaultConfig = DEFAULT_CONFIG;
 
@@ -169,27 +96,6 @@ export class util {
       audioVideo = !!pc.addStream;
     }
 
-    // FIXME: this is not great because in theory it doesn't work for
-    // av-only browsers (?).
-    /*
-    if (!onnegotiationneeded && data) {
-      // sync default check.
-      var negotiationPC = new RTCPeerConnection(defaultConfig, {optional: [{RtpDataChannels: true}]});
-      negotiationPC.onnegotiationneeded = function() {
-        onnegotiationneeded = true;
-        // async check.
-        if (util && util.supports) {
-          util.supports.onnegotiationneeded = true;
-        }
-      };
-      negotiationPC.createDataChannel('_PEERJSNEGOTIATIONTEST');
-
-      setTimeout(function() {
-        negotiationPC.close();
-      }, 1000);
-    }
-    */
-
     if (pc) {
       pc.close();
     }
@@ -214,27 +120,6 @@ export class util {
   static pack = BinaryPack.pack;
   static unpack = BinaryPack.unpack;
 
-  static log(...rest): void {
-    if (!util.debug) return;
-
-    let err = false;
-    const copy = [...rest];
-
-    copy.unshift("PeerJS: ");
-
-    for (let i in copy) {
-      if (copy[i] instanceof Error) {
-        copy[i] = "(" + copy[i].name + ") " + copy[i].message;
-        err = true;
-      }
-    }
-
-    err ? console.error.apply(console, copy) : console.log.apply(console, copy);
-  }
-
-  static warn(..._): void { }
-  static error(..._): void { }
-
   // Binary stuff
 
   private static _dataCount = 1;

+ 45 - 0
test/logger.ts

@@ -0,0 +1,45 @@
+import { expect } from "chai";
+import Logger, { LogLevel } from "../lib/logger";
+
+describe("Logger", function () {
+    it("should be disabled by default", function () {
+        expect(Logger.logLevel).to.eq(LogLevel.Disabled);
+    });
+
+    it("should be accept new log level", function () {
+        const checkedLevels = [];
+
+        Logger.setLogFunction((logLevel) => {
+            checkedLevels.push(logLevel);
+        });
+
+        Logger.logLevel = LogLevel.Warnings;
+
+        expect(Logger.logLevel).to.eq(LogLevel.Warnings);
+
+        Logger.log('');
+        Logger.warn('');
+        Logger.error('');
+
+        expect(checkedLevels).to.deep.eq([LogLevel.Warnings, LogLevel.Errors]);
+    });
+
+    it("should accept new log function", function () {
+        Logger.logLevel = LogLevel.All;
+
+        const checkedLevels = [];
+        const testMessage = 'test it';
+
+        Logger.setLogFunction((logLevel, ...args) => {
+            checkedLevels.push(logLevel);
+
+            expect(args[0]).to.eq(testMessage);
+        });
+
+        Logger.log(testMessage);
+        Logger.warn(testMessage);
+        Logger.error(testMessage);
+
+        expect(checkedLevels).to.deep.eq([LogLevel.All, LogLevel.Warnings, LogLevel.Errors]);
+    });
+});