mcode-log
Version:
A stand-alone package of core code for logging and debugging.
1,297 lines (1,111 loc) • 54.8 kB
JavaScript
// MicroCODE: define this module's name for our 'mcode' package
const MODULE_NAME = 'index.test.js';
const mcode = require('./index.js');
// test/demo code for mcode-log package...
const errorObject =
{
message: 'Please enter the correct login details',
inputError: 'email'
};
const exceptionObject = '{ Exception: "This is an exception, it can be whatever is presented in by the catch clause. }"';
// to test 'logobj()' an Object
const dataObject =
{
userName: 'John Doe',
companyName: 'MicroCODE, Inc.',
author: false,
age: 23.5,
birthDate: new Date('1988-08-21'),
};
const objectArray = [
{name: 'John Doe', company: 'MicroCODE, Inc.', employee: false, age: 23.5, termination: new Date('1988-07-01')},
{name: 'Jane Doe', company: 'MicroCODE, Inc.', employee: false, age: 21, termination: new Date('1981-01-21')},
{name: 'Bob Doe', company: 'MicroCODE, Inc.', employee: true, age: 34, termination: ''},
{name: 'Sam Doe', company: 'MicroCODE, Inc.', employee: false, age: 17.8, termination: new Date('2000-05-07')},
{name: 'Robert Doe', company: 'MicroCODE, Inc.', employee: false, age: 61, termination: new Date('2010-11-30')},
{name: 'Suzy Doe', company: 'MicroCODE, Inc.', employee: false, age: 55, termination: new Date('1982-03-22')},
];
// to test logobj() with JSON
const jsonString = '{ "userName": "Jason Smith", "companyName": "GitHub", "author": true, "age": 28.0, "birthDate": "1998-01-11" }';
// INFO Test
describe('mcode.info', () =>
{
it('mcode.log() should output an *info* message to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the message
mcode.log(`INFO: This is an INFO log event`, MODULE_NAME, 'info');
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("info")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
// WARN Test
describe('mcode.warn', () =>
{
it('mcode.log() should output an *warn* message to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the message
mcode.log(`WARN: This is an WARNING log event`, MODULE_NAME, 'warning');
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("warn")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
// ERROR Test
describe('mcode.error1', () =>
{
it('mcode.log() should output an *error 1* message to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the message
mcode.log(`ERROR1: This is an ERROR log event`, MODULE_NAME, 'error');
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("error")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
// ERROR (+ optional error message) Test
describe('mcode.error2', () =>
{
it('mcode.log() should output an *error 2* message to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the message
mcode.log(`ERROR2: This is an ERROR log event`, MODULE_NAME, 'error', 'ERR=this is the optional error message');
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("error")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")]),
expect.arrayContaining([expect.stringContaining("error:")]),
expect.arrayContaining([expect.stringContaining("ERR=this is the optional error message")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
// ERROR (+ error object) Test
describe('mcode.error3', () =>
{
it('mcode.log() should output an *error 3* message to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the message
mcode.log(`ERROR3: This is an ERROR log object`, MODULE_NAME, 'error', errorObject);
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("error")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")]),
expect.arrayContaining([expect.stringContaining("error:")]),
expect.arrayContaining([expect.stringContaining("Please enter the correct login details")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
// DONE Test
describe('mcode.success', () =>
{
it('mcode.log() should output an *success* message to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the message
mcode.log(`SUCCESS: This is an SUCCESS log event`, MODULE_NAME, 'success');
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("success")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
// DEBUG Test
describe('mcode.debug', () =>
{
it('mcode.log() should output an *debug* message to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the message
mcode.log(`DEBUG: This is an DEBUG log event`, MODULE_NAME, 'debug');
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("debug")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
// UNKNOWN Test
describe('mcode.unknown', () =>
{
it('mcode.log() should output an *undefined severity* message to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the message
mcode.log(`UNKNOWN: This is an UNKNOWN log event`, MODULE_NAME, 'unknown');
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("undefined")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
// EXCEPTION Test
describe('mcode.exception1', () =>
{
it('mcode.log() should output an *exception 1* message to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the message
mcode.log(`EXCEPTION1: This is an EXCEPTION #1 log event`, MODULE_NAME, 'exception');
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("exception")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
// EXCEPTION (+ optional exception object) Test
describe('mcode.exception2', () =>
{
it('mcode.exp() should output an *exception 2* message to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the message
mcode.exp(`EXCEPTION2: This is an EXCEPTION #2 logged object`, MODULE_NAME, exceptionObject);
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("exception w/trace")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")]),
expect.arrayContaining([expect.stringContaining("Exception:")]),
expect.arrayContaining([expect.stringContaining("This is an exception, it can be whatever is presented in by the catch clause.")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
// EXCEPTION (+ optional exception object) Test
describe('mcode.exception3', () =>
{
it('mcode.exp() should output an *exception 3* message to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the message
try
{
throw new Error('This is an an actual EXCEPTION #3');
}
catch (exp)
{
mcode.exp(`EXCEPTION3: This is an EXCEPTION #3 'exp' object`, MODULE_NAME, exp);
}
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("exception w/stack")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")]),
expect.arrayContaining([expect.stringContaining("Error:")]),
expect.arrayContaining([expect.stringContaining(" at ")]),
expect.arrayContaining([expect.stringContaining("This is an EXCEPTION #3 'exp' object")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
// EXCEPTION (+ optional exception object without 'source') Test
describe('mcode.exception4', () =>
{
it('mcode.exp() should output an *exception 4* message and object to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the message
try
{
throw new Error('This is an an actual EXCEPTION #4');
}
catch (exp)
{
mcode.exp(`EXCEPTION4: This is an EXCEPTION #4 'exp' object`, exp); // NO 'SOURCE' parameter
}
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("exception w/stack")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")]),
expect.arrayContaining([expect.stringContaining("Error:")]),
expect.arrayContaining([expect.stringContaining(" at ")]),
expect.arrayContaining([expect.stringContaining("This is an EXCEPTION #4 'exp' object")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
// TRACE Test
describe('mcode.trace', () =>
{
it('mcode.trace() should output an *trace* message to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the message
mcode.trace(`TRACE: This is a FUNCTION call trace, mcode.trace(): ${mcode.trace}`, MODULE_NAME);
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("trace")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
// INFO Test 1
describe('mcode.info1', () =>
{
it('mcode.info() should output an *info* message to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the message
mcode.info(`INFO1: This is an INFO log event`, MODULE_NAME);
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("info")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
// INFO Test 2
describe('mcode.info2', () =>
{
it('mcode.info() should output an *info* message to the console with an Object.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the message
mcode.info(`INFO2: This is an INFO log event with an OBJECT`, dataObject);
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("info")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
// WARN Test
describe('mcode.warn1', () =>
{
it('mcode.warn() should output an *warn* message to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the message
mcode.warn(`WARN1: This is an WARNING log event`, MODULE_NAME);
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("warn")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
// ERROR Test
describe('mcode.error1', () =>
{
it('mcode.error() should output an *error 1* message to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the message
mcode.error(`ERROR1: This is an ERROR log event`, MODULE_NAME);
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("error")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
// ERROR (+ optional error message) Test
describe('mcode.error2', () =>
{
it('mcode.error() should output an *error 2* message to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the message
mcode.error(`ERROR2: This is an ERROR log event`, MODULE_NAME, 'ERR=this is the optional error message');
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("error")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")]),
expect.arrayContaining([expect.stringContaining("error:")]),
expect.arrayContaining([expect.stringContaining("ERR=this is the optional error message")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
// ERROR (+ error object) Test
describe('mcode.error3', () =>
{
it('mcode.error() should output an *error 3* message to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the message
mcode.error(`ERROR3: This is an ERROR log object`, MODULE_NAME, errorObject);
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("error")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")]),
expect.arrayContaining([expect.stringContaining("error:")]),
expect.arrayContaining([expect.stringContaining("Please enter the correct login details")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
// DONE Test
describe('mcode.success', () =>
{
it('mcode.done() should output an *success* message to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the message
mcode.done(`SUCCESS: This is an SUCCESS log event`, MODULE_NAME);
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("success")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
// DEBUG Test
describe('mcode.debug', () =>
{
it('mcode.debug() should output an *debug* message to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the message
mcode.debug(`DEBUG: This is an DEBUG log event`, MODULE_NAME);
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("debug")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
// LOGOBJ Tests
describe('mcode.logobj', () =>
{
it('mcode.logobj() should output a named *object* to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the object
mcode.logobj(`dataObject`, dataObject, MODULE_NAME);
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("{object}")]),
expect.arrayContaining([expect.stringContaining("dataObject:")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
describe('mcode.logobj', () =>
{
it('mcode.logobj() should output a named *function* to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the object
mcode.logobj(`mcode.logobj`, mcode.logobj, MODULE_NAME);
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("function")]),
expect.arrayContaining([expect.stringContaining("mcode.logobj:")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
describe('mcode.logobj', () =>
{
it('mcode.logobj() should output a named *json* to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the object
mcode.logobj(`jsonString`, jsonString, MODULE_NAME);
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("{json}")]),
expect.arrayContaining([expect.stringContaining("jsonString:")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
describe('mcode.logobj', () =>
{
it('mcode.logobj() should output a named *string* to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the object
mcode.logobj(`MODULE_NAME`, MODULE_NAME, MODULE_NAME);
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("{string}")]),
expect.arrayContaining([expect.stringContaining("MODULE_NAME:")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
describe('mcode.logobj', () =>
{
it('mcode.logobj() should output a named *array* to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the object
mcode.logobj(`objectArray`, objectArray, MODULE_NAME);
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("{array}")]),
expect.arrayContaining([expect.stringContaining("objectArray:")]),
expect.arrayContaining([expect.stringContaining(',')]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
// EXPOBJ Tests
describe('mcode.expobj', () =>
{
it('mcode.expobj() should output an *exception* message with an *object* to the console.', () =>
{
// Create a spy on console.log
const consoleSpy = jest.spyOn(console, 'log');
// Call the function that should log the message
try
{
throw new Error('This is an an actual EXCEPTION w/OBJECT');
}
catch (exp)
{
mcode.expobj(`dataObject`, dataObject, MODULE_NAME, exp);
}
// Check that console.log was called with the expected message
expect(consoleSpy.mock.calls).toEqual(
expect.arrayContaining([
expect.arrayContaining([expect.stringContaining("exception w/stack")]),
expect.arrayContaining([expect.stringContaining("[INDEX]")]),
expect.arrayContaining([expect.stringContaining("index.test.js")]),
expect.arrayContaining([expect.stringContaining("exception:")]),
expect.arrayContaining([expect.stringContaining(" at ")]),
expect.arrayContaining([expect.stringContaining("dataObject:")]),
expect.arrayContaining([expect.stringContaining('userName')])
])
);
// Restore the original console.log function
consoleSpy.mockRestore();
});
});
// COLORIZELINES Test
describe('mcode.colorizeLines', () =>
{
it('applies a VT color code to each line', () =>
{
if (!mcode.vt.red) mcode.vt.red = mcode.vt.fg.red;
const input = 'one\ntwo';
const result = mcode.colorizeLines(input, mcode.vt.red);
const expected = `${mcode.vt.fg.red}one\n${mcode.vt.fg.red}two`;
expect(result).toBe(expected);
});
});
// HTML OUTPUT TESTS
describe('mcode.html', () =>
{
describe('HTML color constants', () =>
{
it('mcode.ht should contain HTML inline styles', () =>
{
expect(mcode.ht).toBeDefined();
expect(mcode.ht.reset).toBe('</span>');
expect(mcode.ht.bold).toBe('<span style="font-weight: 600;">');
expect(mcode.ht.fg.red).toBe('<span style="color: red;">');
expect(mcode.ht.nl).toBe('<br/>');
});
});
describe('logHtml function', () =>
{
it('should return HTML string instead of logging to console', () =>
{
const result = mcode.logHtml('Test HTML message', 'test.js', 'info');
// Should return HTML string containing span tags
expect(result).toContain('<span');
expect(result).toContain('</span>');
expect(result).toContain('<br/>');
expect(result).toContain('Test HTML message');
expect(result).toContain('info');
});
it('should handle different severity levels in HTML', () =>
{
const infoResult = mcode.logHtml('Info message', 'test.js', 'info');
const warnResult = mcode.logHtml('Warning message', 'test.js', 'warn');
const errorResult = mcode.logHtml('Error message', 'test.js', 'error');
expect(infoResult).toContain('📣');
expect(warnResult).toContain('⚠️');
expect(errorResult).toContain('⛔');
});
});
describe('logobjHtml function', () =>
{
it('should return HTML formatted object', () =>
{
const testObj = {
name: 'John Doe',
age: 30,
active: true
};
const result = mcode.logobjHtml('testObject', testObj, 'test.js');
expect(result).toContain('<span');
expect(result).toContain('</span>');
expect(result).toContain('<br/>');
expect(result).toContain('testObject');
expect(result).toContain('"John Doe"');
});
});
describe('colorizeLinesHtml function', () =>
{
it('should apply HTML color to each line', () =>
{
const input = 'line one<br/>line two';
const htmlColor = '<span style="color: red;">';
const result = mcode.colorizeLines(input, htmlColor, mcode.ht);
// For HTML, colorizeLines just returns the input unchanged since HTML colors are already applied
expect(result).toBe(input);
});
});
describe('HTML vs VT comparison', () =>
{
it('should produce different output formats for same input', () =>
{
const testMessage = 'Test message';
const testSource = 'test.js';
const vtResult = mcode.log(testMessage, testSource, 'info');
const htmlResult = mcode.logHtml(testMessage, testSource, 'info');
// VT should return simple string status
expect(typeof vtResult).toBe('string');
expect(vtResult).toBe('info: Test message');
// HTML should return formatted HTML string
expect(typeof htmlResult).toBe('string');
expect(htmlResult).toContain('<span');
expect(htmlResult).toContain('<br/>');
expect(htmlResult.length).toBeGreaterThan(vtResult.length);
});
});
describe('HTML logify functionality', () =>
{
it('should format JSON objects with HTML colors', () =>
{
const testObj = {
key1: 'value1',
key2: 42,
key3: true
};
const htmlResult = mcode.logifyHtml(JSON.stringify(testObj));
expect(htmlResult).toContain('<span');
expect(htmlResult).toContain('</span>');
// Should not contain VT escape sequences
expect(htmlResult).not.toContain('\x1b');
});
});
describe('VT logify formatting', () =>
{
it('should not emit blank lines when formatting JSON objects', () =>
{
const nestedObject = {
alpha: {
first: {value: 1},
second: {value: 2}
},
beta: {
inner: {flag: true}
},
gamma: {
list: [1, 2, 3],
empty: null,
big: 12345678901234567890n,
biggerList: [1, "two", 3.0, false, null, 123n],
objectArray: [
{name: 'Alice', age: 30},
{name: 'Bob', age: 25}
]
}
};
mcode.log(nestedObject); // Log normally to console for visual check
const vtResult = mcode.logify(mcode.logifyObject(nestedObject, mcode.vt), mcode.vt);
const vtLines = vtResult.split(mcode.vt.nl);
vtLines.forEach((line, idx) =>
{
const visible = line.replace(/\u001b\[[0-9;]*m/g, '').trim();
if (visible.length === 0)
{
throw new Error(`Detected blank VT output line (index ${idx}).`);
}
});
});
});
describe('HTML exception and trace functions', () =>
{
it('expHtml should return HTML formatted exception log', () =>
{
const result = mcode.expHtml('Test exception', 'test.js', 'Something went wrong');
expect(result).toContain('<div style="color:');
expect(result).toContain('</div>');
expect(result).toContain('Test exception');
expect(result).not.toContain('\x1b'); // No VT escape sequences
});
it('expobjHtml should return HTML formatted exception object log', () =>
{
const testObj = {name: 'test', value: 42};
const result = mcode.expobjHtml('testObj', testObj, 'test.js', 'Object error');
expect(result).toContain('<div style="color:');
expect(result).toContain('</div>');
expect(result).toContain('testObj');
expect(result).not.toContain('\x1b'); // No VT escape sequences
});
it('traceHtml should return HTML formatted trace log', () =>
{
const result = mcode.traceHtml('Function call trace', 'test.js');
expect(result).toContain('<div style="color:');
expect(result).toContain('</div>');
expect(result).toContain('Function call trace');
expect(result).not.toContain('\x1b'); // No VT escape sequences
});
});
describe('JSON Colorization Scheme Tests', () =>
{
describe('VT (Terminal) Color Tests', () =>
{
let consoleSpy;
beforeEach(() =>
{
consoleSpy = jest.spyOn(console, 'log');
});
afterEach(() =>
{
consoleSpy.mockRestore();
});
it('should colorize different data types correctly in VT mode', () =>
{
const testObj = {
stringValue: "Hello World",
integerValue: 42,
floatValue: 3.14,
bigintValue: 123456789012345678901234567890n,
booleanTrue: true,
booleanFalse: false,
nullValue: null,
arrayValue: [1, "two", 3.14, true, false, null]
};
mcode.logobj('VT Color Test', testObj, MODULE_NAME);
const logOutput = consoleSpy.mock.calls.join('');
// Test punctuation colors (cyan + bold punc color in VT)
expect(logOutput).toContain('\x1b[96m\x1b[1m{'); // cyan bold punc punctuation
expect(logOutput).toContain('\x1b[96m\x1b[1m['); // cyan bold punc punctuation
expect(logOutput).toContain('\x1b[96m\x1b[1m:'); // cyan bold punc punctuation
// Test key colors (white in VT)
expect(logOutput).toContain('\x1b[97mstringValue'); // white key
// Test string colors (cyan in VT)
expect(logOutput).toContain('\x1b[96m"Hello World"'); // cyan string
// Test integer colors (blue in VT)
expect(logOutput).toContain('\x1b[94m42'); // blue integer
// Test real/float colors (green in VT)
expect(logOutput).toContain('\x1b[92m3.14'); // green real
// Test boolean colors
expect(logOutput).toContain('\x1b[92mtrue'); // lime true
expect(logOutput).toContain('\x1b[91mfalse'); // red false
// Test null color (gray in VT)
expect(logOutput).toContain('\x1b[90mnull'); // gray null
// Test bigint color (magenta in VT)
expect(logOutput).toContain('\x1b[95m123456789012345678901234567890n'); // magenta bigint
});
it('should handle arrays with mixed data types correctly', () =>
{
const mixedArray1 = [42, 3.14, "string", true, false, null, {data: "data 1 2 3 4 5"}, 123n];
mcode.logobj('Mixed Array Test #1', mixedArray1, MODULE_NAME);
const mixedArray2 = [{data1: "data 1 2 3 4 5"}, {data2: "data 1 2 3 4 5"}, {data3: "data 1 2 3 4 5"}];
mcode.logobj('Object Array Test #2', mixedArray2, MODULE_NAME);
const mixedArray3 = [
{
"column1": "value1",
"column2": true,
"column3": 333,
"object": {
"column1": "value1",
"column2": true,
"column3": 333,
"column4": "value4"
}
},
{
"column1": "value1",
"column2": true,
"column3": 333,
"column4": "value4"
},
{
"column1": "value1",
"column2": true,
"column3": 333,
"column4": "value4",
"object": {
"column1": "value1",
"column2": true,
"column3": 333,
"column4": "value4"
}
},
{
"column1": "value1",
"column2": true,
"column3": 33.3,
"column4": "value4"
},
{
"column1": "value1",
"column2": true,
"column3": 333.333,
"column4": null,
"object": {
"column1": "value1",
"column2": true,
"column3": 333,
"column4": "value4"
}
},
{
"column1": "value1",
"column2": true,
"column3": 333,
"column4": "value4"
},
{
"column1": "value1",
"column2": true,
"column3": 333,
"column4": "value4",
"object": {
"column1": "value1",
"column2": true,
"column3": 333,
"column4": "value4"
}
},
{
"column1": "value1",
"column2": true,
"column3": 333,
"column4": "value4"
},
{
"column1": "value1",
"column2": true,
"column3": 333,
"column4": "value4",
"object": {
"column1": "value1",
"column2": true,
"column3": 333,
"column4": "value4"
}
},
{
"column1": "value1",
"column2": true,
"column3": 333,
"column4": "value4"
},
{
"column1": "value1",
"column2": true,
"column3": 333,
"column4": "value4",
"object": {
"column1": "value1",
"column2": true,
"column3": 333,
"column4": "value4"
}
},
{
"column1": "value1",
"column2": true,
"column3": 333,
"column4": "value4"
},
{
"column1": "value1",
"column2": true,
"column3": 333,
"column4": "value4",
"object": {
"column1": "value1",
"column2": true,
"column3": 333,
"column4": "value4"
}
},
{
"column1": "value1",
"column2": true,
"column3": 333,
"column4": "value4"
}
];
mcode.logobj('Object Array Test #3', mixedArray3, MODULE_NAME);
mcode.log(mixedArray3);
const logOutput = consoleSpy.mock.calls.join('');
// Check that array is properly structured and contains the values
expect(logOutput).toContain('{array}');
expect(logOutput).toContain('Mixed Array Test #1:');
expect(logOutput).toContain('Object Array Test #2:');
expect(logOutput).toContain('Object Array Test #3:');
expect(logOutput).toContain('[');
expect(logOutput).toContain(']');
// Check individual element colors (should match data type colors)
expect(logOutput).toContain('\x1b[94m42'); // blue integer
expect(logOutput).toContain('\x1b[92m3.14'); // green real
expect(logOutput).toContain('\x1b[96m"string"'); // cyan string
expect(logOutput).toContain('\x1b[92mtrue'); // lime true
expect(logOutput).toContain('\x1b[91mfalse'); // red false
expect(logOutput).toContain('\x1b[90mnull'); // gray null
expect(logOutput).toContain('\x1b[95m123n'); // magenta bigint
});
it('should handle nested objects correctly', () =>
{
const nestedObj = {
level1: {
level2: {
stringProp: "nested string",
numberProp: 99
}
}
};
mcode.logobj('Nested Object Test', nestedObj, MODULE_NAME);
const logOutput = consoleSpy.mock.calls.join('');
// Check nested key colors
expect(logOutput).toContain('\x1b[97mlevel1'); // white key
expect(logOutput).toContain('\x1b[97mlevel2'); // white key
expect(logOutput).toContain('\x1b[97mstringProp'); // white key
expect(logOutput).toContain('\x1b[97mnumberProp'); // white key
// Check nested values
expect(logOutput).toContain('\x1b[96m"nested string"'); // cyan string
expect(logOutput).toContain('\x1b[94m99'); // blue integer
});
});
describe('HTML Color Tests', () =>
{
it('should colorize different data types correctly in HTML mode', () =>
{
const testObj = {
stringValue: "Hello World",
integerValue: 42,
floatValue: 3.14,
bigintValue: 123456789012345678901234567890n,
booleanTrue: true,
booleanFalse: false,
nullValue: null,
arrayValue: [1, "two", 3.14, true, false, null]
};
const htmlResult = mcode.logobjHtml('HTML Color Test', testObj, MODULE_NAME);
// Test punctuation colors (cyan punc color in HTML)
expect(htmlResult).toContain('<span style="font-weight: 500; color: #00ffff;">{'); // cyan punc punctuation
expect(htmlResult).toContain('<span style="font-weight: 500; color: #00ffff;">['); // cyan punc punctuation
expect(htmlResult).toContain('<span style="font-weight: 500; color: #00ffff;">:'); // cyan punc punctuation
// Test key colors (#f8f9fa in HTML)
expect(htmlResult).toContain('<span style="font-weight: 300; color: #f8f9fa;">stringValue'); // #f8f9fa key
// Test string colors (cyan in HTML)
expect(htmlResult).toContain('<span style="font-weight: 500; color: #00cccc;">"Hello World"'); // cyan string
// Test integer colors (blue in HTML)
expect(htmlResult).toContain('<span style="font-weight: 600; color: #8bd6ffff;">42'); // blue integer
// Test real/float colors (green in HTML)
expect(htmlResult).toContain('<span style="font-weight: 600; color: #a0ff86;">3.14'); // green real
// Test boolean colors
expect(htmlResult).toContain('<span style="font-weight: 600; color: #00ff00;">true'); // lime true
expect(htmlResult).toContain('<span style="font-weight: 600; color: #ff0000;">false'); // red false
// Test null color (gray in HTML)
expect(htmlResult).toContain('<span style="font-weight: 600; color: #7c7c7c;">null'); // gray null
// Test bigint color (magenta in HTML)
expect(htmlResult).toContain('<span style="font-weight: 600; color: #cf86ff;">123456789012345678901234567890n'); // magenta bigint
// Should not contain VT escape sequences
expect(htmlResult).not.toContain('\x1b');
});
it('should handle arrays with mixed data types correctly in HTML', () =>
{
const mixedArray = [42, 3.14, "string", true, false, null, 123n];
const htmlResult = mcode.logobjHtml('Mixed Array HTML Test', mixedArray, MODULE_NAME);
// Check that array is properly structured in HTML and contains the values
// Note: Array elements in logobjHtml use a different colorization path
expect(htmlResult).toContain('{array}');
expect(htmlResult).toContain('Mixed Array HTML Test:');
expect(htmlResult).toContain('[');
expect(htmlResult).toContain(']');
expect(htmlResult).toContain('42');
expect(htmlResult).toContain('3.14');
expect(htmlResult).toContain('"string"');
expect(htmlResult).toContain('true');
expect(htmlResult).toContain('false');
expect(htmlResult).toContain('null');
expect(htmlResult).toContain('123n');
// Should not contain VT escape sequences
expect(htmlResult).not.toContain('\x1b');
});
});
describe('Edge Cases and Special Values', () =>
{
let consoleSpy;
beforeEach(() =>
{
consoleSpy = jest.spyOn(console, 'log');
});
afterEach(() =>
{
consoleSpy.mockRestore();
});
it('should handle negative numbers correctly', () =>
{
const testObj = {
negativeInt: -42,
negativeFloat: -3.14
};
mcode.logobj('Negative Numbers Test', testObj, MODULE_NAME);
const log