clog/testing/test_logger.py
2023-07-06 20:36:50 +01:00

159 lines
5.9 KiB
Python

# flake8: noqa
import os
import re
import pytest
from clog import Logger
from clog.utils.common import LogLevel
logger = Logger()
class TestLoggingBasics:
@pytest.mark.parametrize(
"value, expected", [
(Logger(), Logger()),
(logger, logger),
(Logger(), logger),
(logger, Logger())
]
)
def test_new_logger_instance(self, value, expected):
assert value is expected
def test_logger_file_default(self):
assert logger.log == os.path.realpath("dump.log")
def test_creation_of_new_logger(self):
assert logger is not Logger.new()
@pytest.mark.parametrize(
"value, expected",
[(".log", '.log'),
(".dump.log", ".dump.log"),
("./non-dir/log", "dump.log"),]
)
def test_using_different_log_file(self, value, expected):
global logger
logger = logger.new(out_f=value)
os.remove(logger.log)
assert Logger().log == os.path.realpath(expected).strip('"')
class TestLoggingSTD:
global logger
logger = logger.new()
@pytest.mark.parametrize(
"value, expected, s, e", [
(*("Normal text to STDOUT",) * 2, None, None),
(*("Normal test with a newline\nto STDOUT",) * 2, None, None),
(("Text", "with", "hyphens"), "Text-with-hyphens", "-", None),
("Text here...", "Text here...\r", None, '\r')
]
)
def test_message_written_to_stdout(self, value, expected, s, e, capture_stdpipe):
if isinstance(value, tuple):
logger.printLog(*value, level=LogLevel.NORMAL, sep=s, end=e)
else:
logger.printLog(value, level=LogLevel.NORMAL, sep=s, end=e)
assert capture_stdpipe['stdout'].rstrip('\n') == expected and capture_stdpipe['stderr'] == ""
@pytest.mark.parametrize(
"value, expected, s, e", [
(*("Normal text to STDOUT",) * 2, None, None),
(*("Normal test with a newline\nto STDOUT",) * 2, None, None),
(("Text", "with", "hyphens"), "Text-with-hyphens", "-", None),
("Text here...", "Text here...\r", None, '\r')
]
)
def test_message_written_to_stderr(self, value, expected, s, e, capture_stdpipe):
if isinstance(value, tuple):
logger.printLog(*value, level=LogLevel.DEBUG, sep=s, end=e)
else:
logger.printLog(value, level=LogLevel.DEBUG, sep=s, end=e)
assert capture_stdpipe['stderr'].rstrip('\n') == expected and capture_stdpipe['stdout'] == ""
def test_message_not_on_std_pipe(self, capture_stdpipe):
with open(os.path.devnull, 'w') as devnull:
Logger.printLog("Message isn't sent to STDOUT or STDERR", file=devnull)
assert capture_stdpipe['stdout'] == "" and capture_stdpipe['stderr'] == ""
@pytest.mark.skip
def test_when_file_descriptor_redirect_is_given(self):
### :@Ethan: OK this test requires a little explaining as to what's going on
# and why it's happening. Since this project was pulled out of another and
# became standalone, the original program which made use of this system was
# designed to prevent writes with ANSI escape sequences on PIPE when a file
# descriptor redirect was given from the command-line. That logic still exists
# and here we invoke that behavour for testing by running a bit of Python script
# from the terminal.
#
#
# :@UPDATE: if anyone knows how to test this behaviour by invoking that a TTY
# is present in a subprocess call, create an Issue or a PR with the appropriate
# code to get something like that working. I've spent way too much time on trying
# to prove the system works and behaves how it should, but you can confirm this
# happens by calling the `Logger.printLog()` method from an external script
# and performing a file descriptor redirect to a file. If you don't see ASNI
# escape sequences, the system works correctly, and you can call the module
# again without redirect to ensure the terminal gets coloured output on log levels
# `LogLevel.DEBUG` or higher.
...
def test_print_log_does_not_handle_string_paths(self, capture_stdpipe):
Logger.printLog("This fails correctly", file="bad_file.txt")
assert capture_stdpipe['stderr'] != ""
class TestLogging2File:
def test_print_log_2_file_handles_string_paths(self, capture_stdpipe):
Logger.printLog2File("Hello, World!", file=logger.log, mode='w')
assert capture_stdpipe['stdout'] == "" and capture_stdpipe['stderr'] == ""
def test_print_log_2_file_writes_to_file(self):
Logger.printLog2File("Message to log", file=logger.log, mode='w')
with open(logger.log, 'r') as f:
assert re.match('^.*Message to log$', f.read())
class TestPseudoLogs:
global logger
logger = logger.new()
@pytest.mark.parametrize(
"value", [Logger().debug, Logger().warn, Logger().error]
)
def test_pseudologs_are_instance_bound(self, value):
assert hasattr(value, '__self__')
@pytest.mark.parametrize(
"value, ln, lv", [
(logger.debug, 1, "DEBUG"),
(logger.warn, 2, "WARN"),
(logger.error, 3, "ERROR"),
]
)
def test_pseudologs_write_to_file(self, value, ln, lv):
value("Pseudolog to file")
with open(logger.log, 'r') as f:
assert re.match(f'^.*{lv}\\s+Pseudolog to file$', f.readlines()[ln])
@pytest.mark.parametrize(
"value, ln", [
(logger.debug, 4),
(logger.warn, 5),
(logger.error, 6),
]
)
def test_pseudologs_write_to_file_and_console(self, value, ln, capture_stdpipe):
value("Pseudolog to file and console", strace=False).withConsole()
with open(logger.log, 'r') as f:
assert re.match(f'^.*{capture_stdpipe["stderr"]}$', f.readlines()[ln])