340 lines
12 KiB
MQL5
340 lines
12 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| UnitTests.mq5 |
|
|
//| Unit Tests for Package logger |
|
|
//| Organization: douglasrechia |
|
|
//+------------------------------------------------------------------+
|
|
|
|
#include "../knitpkg/build/BuildInfo.mqh"
|
|
|
|
#property copyright "Douglas Rechia"
|
|
#property link "https://knitpkg.dev"
|
|
#property description ""
|
|
#property description "Version: " + MANIFEST_VERSION
|
|
#property description ""
|
|
#property description "Description: Unit tests for package logger"
|
|
#property description "Organization: douglasrechia"
|
|
#property description "Author: Douglas Rechia"
|
|
#property description "License: MIT"
|
|
#property description ""
|
|
#property description "Powered by KnitPkg for MetaTrader"
|
|
#property description "https://knitpkg.dev"
|
|
|
|
#include "../knitpkg/include/douglasrechia/logger/Logger.mqh"
|
|
#include "../knitpkg/include/douglasrechia/logger/handlers/PrintLogger.mqh"
|
|
#include "../knitpkg/include/douglasrechia/logger/handlers/FileLogger.mqh"
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Asserts log file content matches expected patterns |
|
|
//+------------------------------------------------------------------+
|
|
bool AssertLogContent(string filePath, string &expectedPatterns[], string testName)
|
|
{
|
|
int fileHandle = FileOpen(filePath, FILE_READ | FILE_TXT | FILE_ANSI);
|
|
if(fileHandle == INVALID_HANDLE) {
|
|
PrintFormat("%s: Failed to open log file for verification", testName);
|
|
return false;
|
|
}
|
|
|
|
int patternIndex = 0;
|
|
bool allMatch = true;
|
|
int lineNumber = 0;
|
|
|
|
while(!FileIsEnding(fileHandle)) {
|
|
string line = FileReadString(fileHandle);
|
|
if(line == "") continue;
|
|
|
|
lineNumber++;
|
|
|
|
if(patternIndex >= ArraySize(expectedPatterns)) {
|
|
PrintFormat("%s: More lines than expected in log file", testName);
|
|
allMatch = false;
|
|
break;
|
|
}
|
|
|
|
// Check if line contains expected pattern
|
|
if(StringFind(line, expectedPatterns[patternIndex]) < 0) {
|
|
PrintFormat("%s: Line %d mismatch. Expected to contain: '%s', Got: '%s'",
|
|
testName, lineNumber, expectedPatterns[patternIndex], line);
|
|
allMatch = false;
|
|
}
|
|
patternIndex++;
|
|
|
|
if(StringFind(line, expectedPatterns[patternIndex]) < 0) {
|
|
PrintFormat("%s: Line %d mismatch. Expected to contain: '%s', Got: '%s'",
|
|
testName, lineNumber, expectedPatterns[patternIndex], line);
|
|
allMatch = false;
|
|
}
|
|
patternIndex++;
|
|
}
|
|
|
|
FileClose(fileHandle);
|
|
|
|
if(patternIndex < ArraySize(expectedPatterns)) {
|
|
PrintFormat("%s: Expected %d lines, got %d", testName, ArraySize(expectedPatterns), patternIndex);
|
|
allMatch = false;
|
|
}
|
|
|
|
return allMatch;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool TestAll()
|
|
{
|
|
douglasrechia::Logger* g_log = new douglasrechia::Logger(__FILE__, douglasrechia::LOG_LEVEL_DEBUG);
|
|
g_log.AddHandler(new douglasrechia::FileLogger("logs/log_test_all.log", true, false));
|
|
|
|
g_log.Info("TestAll", "info");
|
|
g_log.Debug("TestAll", "debug");
|
|
g_log.Warn("TestAll", "warn");
|
|
g_log.Error("TestAll", "error");
|
|
|
|
g_log.Info("TestAll info");
|
|
g_log.Debug("TestAll debug");
|
|
g_log.Warn("TestAll warn");
|
|
g_log.Error("TestAll error");
|
|
|
|
delete g_log;
|
|
|
|
string expectedPatterns[] = {
|
|
"[UnitTests.mq5][INFO ] ", "| TestAll | info",
|
|
"[UnitTests.mq5][DEBUG] ", "| TestAll | debug",
|
|
"[UnitTests.mq5][WARN ] ", "| TestAll | warn",
|
|
"[UnitTests.mq5][ERROR] ", "| TestAll | error",
|
|
"[UnitTests.mq5][INFO ] ", "| TestAll info",
|
|
"[UnitTests.mq5][DEBUG] ", "| TestAll debug",
|
|
"[UnitTests.mq5][WARN ] ", "| TestAll warn",
|
|
"[UnitTests.mq5][ERROR] ", "| TestAll error"
|
|
};
|
|
|
|
return AssertLogContent("logs/log_test_all.log", expectedPatterns, "TestAll");
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool TestInfo()
|
|
{
|
|
douglasrechia::Logger* g_log = new douglasrechia::Logger(__FILE__, douglasrechia::LOG_LEVEL_INFO);
|
|
g_log.AddHandler(new douglasrechia::FileLogger("logs/log_test_info.log", true, false));
|
|
|
|
g_log.Info("TestInfo", "info");
|
|
g_log.Debug("TestInfo", "debug");
|
|
g_log.Warn("TestInfo", "warn");
|
|
g_log.Error("TestInfo", "error");
|
|
|
|
g_log.Info("TestInfo info");
|
|
g_log.Debug("TestInfo debug");
|
|
g_log.Warn("TestInfo warn");
|
|
g_log.Error("TestInfo error");
|
|
|
|
delete g_log;
|
|
|
|
string expectedPatterns[] = {
|
|
"[UnitTests.mq5][INFO ] ", "| TestInfo | info",
|
|
"[UnitTests.mq5][WARN ] ", "| TestInfo | warn",
|
|
"[UnitTests.mq5][ERROR] ", "| TestInfo | error",
|
|
"[UnitTests.mq5][INFO ] ", "| TestInfo info",
|
|
"[UnitTests.mq5][WARN ] ", "| TestInfo warn",
|
|
"[UnitTests.mq5][ERROR] ", "| TestInfo error"
|
|
};
|
|
|
|
return AssertLogContent("logs/log_test_info.log", expectedPatterns, "TestInfo");
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool TestWarn()
|
|
{
|
|
douglasrechia::Logger* g_log = new douglasrechia::Logger(__FILE__, douglasrechia::LOG_LEVEL_WARN);
|
|
g_log.AddHandler(new douglasrechia::FileLogger("logs/log_test_warn.log", true, false));
|
|
|
|
g_log.Info("TestWarn", "info");
|
|
g_log.Debug("TestWarn", "debug");
|
|
g_log.Warn("TestWarn", "warn");
|
|
g_log.Error("TestWarn", "error");
|
|
|
|
g_log.Info("TestWarn info");
|
|
g_log.Debug("TestWarn debug");
|
|
g_log.Warn("TestWarn warn");
|
|
g_log.Error("TestWarn error");
|
|
|
|
delete g_log;
|
|
|
|
string expectedPatterns[] = {
|
|
"[UnitTests.mq5][WARN ] ", "| TestWarn | warn",
|
|
"[UnitTests.mq5][ERROR] ", "| TestWarn | error",
|
|
"[UnitTests.mq5][WARN ] ", "| TestWarn warn",
|
|
"[UnitTests.mq5][ERROR] ", "| TestWarn error"
|
|
};
|
|
|
|
return AssertLogContent("logs/log_test_warn.log", expectedPatterns, "TestWarn");
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool TestError()
|
|
{
|
|
douglasrechia::Logger* g_log = new douglasrechia::Logger(__FILE__, douglasrechia::LOG_LEVEL_ERROR);
|
|
g_log.AddHandler(new douglasrechia::FileLogger("logs/log_test_error.log", true, false));
|
|
|
|
g_log.Info("TestError", "info");
|
|
g_log.Debug("TestError", "debug");
|
|
g_log.Warn("TestError", "warn");
|
|
g_log.Error("TestError", "error");
|
|
|
|
g_log.Info("TestError info");
|
|
g_log.Debug("TestError debug");
|
|
g_log.Warn("TestError warn");
|
|
g_log.Error("TestError error");
|
|
|
|
delete g_log;
|
|
|
|
string expectedPatterns[] = {
|
|
"[UnitTests.mq5][ERROR] ", "| TestError | error",
|
|
"[UnitTests.mq5][ERROR] ", "| TestError error"
|
|
};
|
|
|
|
return AssertLogContent("logs/log_test_error.log", expectedPatterns, "TestError");
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool TestErrorAppend()
|
|
{
|
|
douglasrechia::Logger* g_log = new douglasrechia::Logger(__FILE__, douglasrechia::LOG_LEVEL_ERROR);
|
|
g_log.AddHandler(new douglasrechia::FileLogger("logs/log_test_error.log", true, false));
|
|
|
|
g_log.Info("TestError", "info");
|
|
g_log.Debug("TestError", "debug");
|
|
g_log.Warn("TestError", "warn");
|
|
g_log.Error("TestError", "error");
|
|
|
|
g_log.Info("TestError info");
|
|
g_log.Debug("TestError debug");
|
|
g_log.Warn("TestError warn");
|
|
g_log.Error("TestError error");
|
|
|
|
delete g_log;
|
|
|
|
string expectedPatterns1[] = {
|
|
"[UnitTests.mq5][ERROR] ", "| TestError | error",
|
|
"[UnitTests.mq5][ERROR] ", "| TestError error"
|
|
};
|
|
|
|
bool check1 = AssertLogContent("logs/log_test_error.log", expectedPatterns1, "TestError");
|
|
|
|
g_log = new douglasrechia::Logger(__FILE__, douglasrechia::LOG_LEVEL_ERROR);
|
|
g_log.AddHandler(new douglasrechia::FileLogger("logs/log_test_error.log", true, true));
|
|
|
|
g_log.Info("TestError", "info");
|
|
g_log.Debug("TestError", "debug");
|
|
g_log.Warn("TestError", "warn");
|
|
g_log.Error("TestError", "error");
|
|
|
|
g_log.Info("TestError info");
|
|
g_log.Debug("TestError debug");
|
|
g_log.Warn("TestError warn");
|
|
g_log.Error("TestError error");
|
|
|
|
delete g_log;
|
|
|
|
string expectedPatterns2[] = {
|
|
"[UnitTests.mq5][ERROR] ", "| TestError | error",
|
|
"[UnitTests.mq5][ERROR] ", "| TestError error",
|
|
"[UnitTests.mq5][ERROR] ", "| TestError | error",
|
|
"[UnitTests.mq5][ERROR] ", "| TestError error"
|
|
};
|
|
|
|
bool check2 = AssertLogContent("logs/log_test_error.log", expectedPatterns2, "TestError");
|
|
|
|
return check1 && check2;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| DoTests |
|
|
//+------------------------------------------------------------------+
|
|
void DoTests(int &testsPerformed,int &testsPassed)
|
|
{
|
|
string testName="";
|
|
|
|
//--- TestAll
|
|
testsPerformed++;
|
|
testName="TestAll";
|
|
if(TestAll())
|
|
{
|
|
testsPassed++;
|
|
PrintFormat("%s pass",testName);
|
|
}
|
|
else
|
|
PrintFormat("%s failed",testName);
|
|
|
|
//--- TestInfo
|
|
testsPerformed++;
|
|
testName="TestInfo";
|
|
if(TestInfo())
|
|
{
|
|
testsPassed++;
|
|
PrintFormat("%s pass",testName);
|
|
}
|
|
else
|
|
PrintFormat("%s failed",testName);
|
|
|
|
//--- TestWarn
|
|
testsPerformed++;
|
|
testName="TestWarn";
|
|
if(TestWarn())
|
|
{
|
|
testsPassed++;
|
|
PrintFormat("%s pass",testName);
|
|
}
|
|
else
|
|
PrintFormat("%s failed",testName);
|
|
|
|
//--- TestError
|
|
testsPerformed++;
|
|
testName="TestError";
|
|
if(TestError())
|
|
{
|
|
testsPassed++;
|
|
PrintFormat("%s pass",testName);
|
|
}
|
|
else
|
|
PrintFormat("%s failed",testName);
|
|
|
|
//--- TestErrorAppend
|
|
testsPerformed++;
|
|
testName="TestErrorAppend";
|
|
if(TestErrorAppend())
|
|
{
|
|
testsPassed++;
|
|
PrintFormat("%s pass",testName);
|
|
}
|
|
else
|
|
PrintFormat("%s failed",testName);
|
|
|
|
//---
|
|
// Add more tests here as needed
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| UnitTests() |
|
|
//+------------------------------------------------------------------+
|
|
void UnitTests(const string packageName)
|
|
{
|
|
PrintFormat("Unit tests for Package %s\n",packageName);
|
|
//--- initial values
|
|
int testsPerformed=0;
|
|
int testsPassed=0;
|
|
//--- test distributions
|
|
DoTests(testsPerformed,testsPassed);
|
|
//--- print statistics
|
|
PrintFormat("\n%d of %d passed",testsPassed,testsPerformed);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Script program start function |
|
|
//+------------------------------------------------------------------+
|
|
void OnStart()
|
|
{
|
|
UnitTests("logger");
|
|
}
|
|
//+------------------------------------------------------------------+
|