@phoenix-plugin-registry/brackets-markdown-preview
Version:
Markdown live preview incl. detached window, code syntax highlighting, output themes, adaptive preview width, graphical checkboxes, activation on start...
179 lines (164 loc) • 8.26 kB
JavaScript
/**
* @module ExtLoggingUtils
* @file Functions and classes helping to develop and debug a brackets extension using structured 'use case oriented' log entries (hence the object type name 'LogCase').
* @author Loïs Bégué
* @license MIT license (MIT)
* @copyright Copyright (c) 2017 Loïs Bégué
*/
/*global define, $, brackets, window */
define(function (require, exports, module) {
"use strict";
/**
* The log case object can be used to debug a particular use/test case i.e. a particular code block.
* The log entries are collected in a case specific array (e.g. to review them at a later stage).
* The log entries can optionaly show up directly in the console. An optional time stamp can be added to the entries.
* @typedef LogCase
* @type {object}
* @property {number} ID - the ID of the log/test case (automatically incremented).
* @property {string} description - The description of the logcase.
* @property {string[]} logArray - The array of log entries of the logcase.
* @property {boolean} verbose - directly writes the logs in the console when 'true'
* @property {function} log - create, save a log entry and (optionally) write it to the console
* @property {string} fulllog - the entire log of the log case object (each entry on a new line)
* @property {function} start - Registers the start of the log case and writes an entry in the log
* @property {function} end - Registers the end of the log case and writes an entry in the log
* @property {boolean} timed - Writes a time stamp on each log entry when set to 'true'
* @property {boolean} started - 'true' when the 'start' method has been called
* @property {boolean} completed - 'true' when the 'end' method has been called
* @property {object} startTime - the date object correpsonding to the start of the case
* @property {object} endTime - the date object correpsonding to the end of the case
*/
// Register local extension modules
var ExtUtils = require("scripts/ExtUtils");
// Module variables and constants
var _logCaseID = 0; // 0 = first log case ID
var logSeparator = "-----------------------------------------------------------";
const defaultDesc = "no description available";
/**
* Insert an entry in the log of the case and (optionally) write it to the console.
* May add a time stamp to the entry when the 'timed' option is set to 'true'.
* If no text is provided, a divider/separator line will be inserted instead.
* If 'timed' is 'true' and no time stamp is provided, the current date will be used as a time stamp.
* @author Loïs Bégué
* @this
* @param {string} [sometext = logSeparator] The text of the log entry (or the default 'separator line' if no text is provided)
* @param {object} [timeStamp = null] A time stamp (Date object), that should be attached to the log entry when the timed option is on.
*/
function log(sometext = logSeparator, timeStamp = null) {
let timeString = (true === this.timed) ? "[" + ( timeStamp ? timeStamp.toLocaleString() : (new Date()).toLocaleString()) + "]" : "";
let textToLog = "[C" + ExtUtils.padNumber(this.ID) + "] " + timeString + sometext;
if (true === this.verbose) {
console.log(textToLog);
}
this.logArray.push(textToLog);
}
/**
* Function returning a string containing all the log entries (one entry per line)
* @author Loïs Bégué
* @returns {string} The full log of the log case object
* @this
*/
function getFullLog(){
return this.logArray.join("\n");
}
/**
* Ends the log case and insert a corresponding log entry
* @author Loïs Bégué
* @this
*/
function endLogCase(){
this.completed = true;
this.endTime = new Date();
let t = "[END] ";
this.log( ExtUtils.padText(t, 80, "="), this.endTime);
}
/**
* Starts the log case and insert a log entry containing the case description
* @author Loïs Bégué
* @this
*/
function startLogCase(){
this.started = true;
this.startTime = new Date();
let t = "[START] " + this.description + " ";
this.log( ExtUtils.padText(t, 80, "="), this.startTime);
}
/**
* Create a LogCase object and give it back to the caller
* @author Loïs Bégué
* @param {string} [logCaseDescription = defaultDesc] The description of the test case to be logged
* @param {boolean} [verbose = false] Displays the logs immediately in the console when set to 'true' Use 'fulllog' property to retrieve the log afterwards
* @param {boolean} [timed = false] Adds a time stamp to the log entries when set to 'true'
* @returns {LogCase} a new log case object
*/
function createLogCase(logCaseDescription = defaultDesc, verbose = false, timed = false){
let newLogCase = {};
newLogCase["description"] = logCaseDescription;
newLogCase["ID"] = _logCaseID++;
newLogCase["logArray"] = [];
newLogCase["verbose"] = verbose;
newLogCase["log"] = log;
newLogCase["fullLog"] = getFullLog;
newLogCase["end"] = endLogCase;
newLogCase["start"] = startLogCase;
newLogCase["started"] = false;
newLogCase["completed"] = false;
newLogCase["timed"] = timed;
newLogCase["startTime"] = Date.now();
newLogCase["endTime"] = newLogCase["startTime"];
return newLogCase;
}
/**
* Self test function to check the module functionality (also suitable as usage example)
* @author Loïs Bégué
* @this
*/
function selfTest(){
// instanciate the selftest logcase: verbose=true, timed=false
let selfTestLogCase = this.createLogCase("Self Test of the module 'ExtLoggingUtils'", true, false);
selfTestLogCase.start();
selfTestLogCase.log("Execute the first (nested) code block to be tested...");
{
// instanciate the first logCase
let myLogCase1 = this.createLogCase("This is the first code to be tested", true, false);
// start
myLogCase1.start();
// log
myLogCase1.log("Before Action #1");
// application code simulation
console.log("...Action #1...");
// log
myLogCase1.log("Before Action #2");
// application code simulation
console.log("...Action #2...");
// last log before closing (end of the code block has been reached safelly so far)
myLogCase1.end();
}
selfTestLogCase.log("Execute the second (nested) code block to be tested...");
{
// instanciate the second logCase
let myLogCase2 = this.createLogCase("This is the second code to be tested", true, false);
// start
myLogCase2.start();
// log
myLogCase2.log("Before Action #1");
// application code simulation
console.log("...Action #1...");
// log
myLogCase2.log("Before Action #2");
// application code simulation
console.log("...Action #2...");
// last log before closing (end of the code block has been reached safelly so far)
myLogCase2.end();
}
selfTestLogCase.end();
// Display the full log of the "selfTest Log Case"
console.log("SELF TEST LOG CASE : FULLLOG\n" + selfTestLogCase.fullLog());
return selfTestLogCase.fullLog();
}
exports.createLogCase = createLogCase;
exports.selfTest = selfTest;
});
/* TODO: improve code = in particular make all objects rock strong using private members/methods
e.g. using the following technics https://philipwalton.com/articles/implementing-private-and-protected-members-in-javascript/ or
https://stackoverflow.com/questions/34869352/how-to-declare-private-variables-and-private-methods-in-es6-class */