| from fontTools.misc.py23 import * |
| from fontTools.misc.loggingTools import ( |
| LevelFormatter, |
| Timer, |
| configLogger, |
| ChannelsFilter, |
| LogMixin, |
| ) |
| import logging |
| import textwrap |
| import time |
| import re |
| import pytest |
| |
| |
| def logger_name_generator(): |
| basename = "fontTools.test#" |
| num = 1 |
| while True: |
| yield basename+str(num) |
| num += 1 |
| |
| unique_logger_name = logger_name_generator() |
| |
| |
| @pytest.fixture |
| def logger(): |
| log = logging.getLogger(next(unique_logger_name)) |
| configLogger(logger=log, level="DEBUG", stream=StringIO()) |
| return log |
| |
| |
| def test_LevelFormatter(): |
| stream = StringIO() |
| handler = logging.StreamHandler(stream) |
| formatter = LevelFormatter( |
| fmt={ |
| '*': '[%(levelname)s] %(message)s', |
| 'DEBUG': '%(name)s [%(levelname)s] %(message)s', |
| 'INFO': '%(message)s', |
| }) |
| handler.setFormatter(formatter) |
| name = next(unique_logger_name) |
| log = logging.getLogger(name) |
| log.setLevel(logging.DEBUG) |
| log.addHandler(handler) |
| |
| log.debug("this uses a custom format string") |
| log.info("this also uses a custom format string") |
| log.warning("this one uses the default format string") |
| |
| assert stream.getvalue() == textwrap.dedent("""\ |
| %s [DEBUG] this uses a custom format string |
| this also uses a custom format string |
| [WARNING] this one uses the default format string |
| """ % name) |
| |
| |
| class TimerTest(object): |
| |
| def test_split(self): |
| timer = Timer() |
| time.sleep(0.01) |
| fist_lap = timer.split() |
| assert timer.elapsed == fist_lap |
| time.sleep(0.1) |
| second_lap = timer.split() |
| assert second_lap > fist_lap |
| assert timer.elapsed == second_lap |
| |
| def test_time(self): |
| timer = Timer() |
| time.sleep(0.01) |
| overall_time = timer.time() |
| assert overall_time > 0 |
| |
| def test_context_manager(self): |
| with Timer() as t: |
| time.sleep(0.01) |
| assert t.elapsed > 0 |
| |
| def test_using_logger(self, logger): |
| with Timer(logger, 'do something'): |
| time.sleep(0.01) |
| |
| assert re.match( |
| r"Took [0-9]\.[0-9]{3}s to do something", |
| logger.handlers[0].stream.getvalue()) |
| |
| def test_using_logger_calling_instance(self, logger): |
| timer = Timer(logger) |
| with timer(): |
| time.sleep(0.01) |
| |
| assert re.match( |
| r"elapsed time: [0-9]\.[0-9]{3}s", |
| logger.handlers[0].stream.getvalue()) |
| |
| # do it again but with custom level |
| with timer('redo it', level=logging.WARNING): |
| time.sleep(0.02) |
| |
| assert re.search( |
| r"WARNING: Took [0-9]\.[0-9]{3}s to redo it", |
| logger.handlers[0].stream.getvalue()) |
| |
| def test_function_decorator(self, logger): |
| timer = Timer(logger) |
| |
| @timer() |
| def test1(): |
| time.sleep(0.01) |
| @timer('run test 2', level=logging.INFO) |
| def test2(): |
| time.sleep(0.02) |
| |
| test1() |
| |
| assert re.match( |
| r"Took [0-9]\.[0-9]{3}s to run 'test1'", |
| logger.handlers[0].stream.getvalue()) |
| |
| test2() |
| |
| assert re.search( |
| r"Took [0-9]\.[0-9]{3}s to run test 2", |
| logger.handlers[0].stream.getvalue()) |
| |
| |
| def test_ChannelsFilter(logger): |
| n = logger.name |
| filtr = ChannelsFilter(n+".A.B", n+".C.D") |
| handler = logger.handlers[0] |
| handler.addFilter(filtr) |
| stream = handler.stream |
| |
| logging.getLogger(n+".A.B").debug('this record passes through') |
| assert 'this record passes through' in stream.getvalue() |
| |
| logging.getLogger(n+'.A.B.C').debug('records from children also pass') |
| assert 'records from children also pass' in stream.getvalue() |
| |
| logging.getLogger(n+'.C.D').debug('this one as well') |
| assert 'this one as well' in stream.getvalue() |
| |
| logging.getLogger(n+'.A.B.').debug('also this one') |
| assert 'also this one' in stream.getvalue() |
| |
| before = stream.getvalue() |
| logging.getLogger(n+'.A.F').debug('but this one does not!') |
| assert before == stream.getvalue() |
| |
| logging.getLogger(n+'.C.DE').debug('neither this one!') |
| assert before == stream.getvalue() |
| |
| |
| def test_LogMixin(): |
| |
| class Base(object): |
| pass |
| |
| class A(LogMixin, Base): |
| pass |
| |
| class B(A): |
| pass |
| |
| a = A() |
| b = B() |
| |
| assert hasattr(a, 'log') |
| assert hasattr(b, 'log') |
| assert isinstance(a.log, logging.Logger) |
| assert isinstance(b.log, logging.Logger) |
| assert a.log.name == "loggingTools_test.A" |
| assert b.log.name == "loggingTools_test.B" |