# Path: sen/tui/widgets/list/common.py
# def strip_from_ansi_esc_sequences(text):
#     """
#     find ANSI escape sequences in text and remove them
# 
#     :param text: str
#     :return: list, should be passed to ListBox
#     """
#     # esc[ + values + control character
#     # h, l, p commands are complicated, let's ignore them
#     seq_regex = r"\x1b\[[0-9;]*[mKJusDCBAfH]"
#     regex = re.compile(seq_regex)
#     start = 0
#     response = ""
#     for match in regex.finditer(text):
#         end = match.start()
#         response += text[start:end]
# 
#         start = match.end()
#     response += text[start:len(text)]
#     return response
# 
# Path: sen/util.py
# def _ensure_unicode(s):
#     try:
#         return s.decode("utf-8")
#     except AttributeError:
#         return s
# 
# def log_traceback(func):
#     @functools.wraps(func)
#     def wrapper(*args, **kwargs):
#         logger.info("function %s is about to be started", func)
#         try:
#             response = func(*args, **kwargs)
#         except Exception:
#             log_last_traceback()
#         else:
#             logger.info("function %s finished", func)
#             # TODO: how long it took?
#             return response
#     return wrapper
# 
# def repeater(call, args=None, kwargs=None, retries=4):
#     """
#     repeat call x-times: docker API is just awesome
# 
#     :param call: function
#     :param args: tuple, args for function
#     :param kwargs: dict, kwargs for function
#     :param retries: int, how many times we try?
#     :return: response of the call
#     """
#     args = args or ()
#     kwargs = kwargs or {}
#     t = 1.0
#     for x in range(retries):
#         try:
#             return call(*args, **kwargs)
#         except APIError as ex:
#             logger.error("query #%d: docker returned an error: %r", x, ex)
#         except Exception as ex:
#             # this may be pretty bad
#             log_last_traceback()
#             logger.error("query #%d: generic error: %r", x, ex)
#         t *= 2
#         time.sleep(t)
# 
# def humanize_time(value):
#     abbrevs = (
#         (1, "now"),
#         (2, "{seconds} seconds ago"),
#         (59, "{seconds} seconds ago"),
#         (60, "{minutes} minute ago"),
#         (119, "{minutes} minute ago"),
#         (120, "{minutes} minutes ago"),
#         (3599, "{minutes} minutes ago"),
#         (3600, "{hours} hour ago"),
#         (7199, "{hours} hour ago"),
#         (86399, "{hours} hours ago"),
#         (86400, "{days} day ago"),
#         (172799, "{days} day ago"),
#         (172800, "{days} days ago"),
#         (172800, "{days} days ago"),
#         (2591999, "{days} days ago"),
#         (2592000, "{months} month ago"),
#         (5183999, "{months} month ago"),
#         (5184000, "{months} months ago"),
#     )
#     n = datetime.now()
#     delta = n - value
#     for guard, message in abbrevs:
#         s = int(delta.total_seconds())
#         if guard >= s:
#             break
#     return message.format(seconds=delta.seconds, minutes=int(delta.seconds // 60),
#                           hours=int(delta.seconds // 3600), days=delta.days,
#                           months=int(delta.days // 30))
# 
# class OrderedSet(list):
#     def append(self, p_object):
#         if p_object in self:
#             self.remove(p_object)
#         return super().append(p_object)


import logging
import time
import pytest
from concurrent.futures.thread import ThreadPoolExecutor
from datetime import datetime, timedelta
from sen.tui.widgets.list.common import strip_from_ansi_esc_sequences
from sen.util import _ensure_unicode, log_traceback, repeater, humanize_time, \
    OrderedSet
# -*- coding: utf-8 -*-




@pytest.mark.parametrize("inp,expected", [
    ("a", "a"),
    (b"a", "a"),
    ("\u2606", "☆"),
    (b'\xe2\x98\x86', "☆"),
])
def test_ensure_unicode(inp, expected):
    assert _ensure_unicode(inp) == expected


def test_log_traceback(caplog):
    @log_traceback
    def f():
        raise Exception()
    caplog.set_level(logging.DEBUG)
    f()
    assert caplog.records[0].message.endswith(" is about to be started")
    assert caplog.records[1].message.startswith("Traceback")
    assert caplog.records[1].message.endswith("Exception\n")


def test_log_traceback_without_tb(caplog):

# Path: sen/tui/widgets/list/common.py
# def strip_from_ansi_esc_sequences(text):
#     """
#     find ANSI escape sequences in text and remove them
# 
#     :param text: str
#     :return: list, should be passed to ListBox
#     """
#     # esc[ + values + control character
#     # h, l, p commands are complicated, let's ignore them
#     seq_regex = r"\x1b\[[0-9;]*[mKJusDCBAfH]"
#     regex = re.compile(seq_regex)
#     start = 0
#     response = ""
#     for match in regex.finditer(text):
#         end = match.start()
#         response += text[start:end]
# 
#         start = match.end()
#     response += text[start:len(text)]
#     return response
# 
# Path: sen/util.py
# def _ensure_unicode(s):
#     try:
#         return s.decode("utf-8")
#     except AttributeError:
#         return s
# 
# def log_traceback(func):
#     @functools.wraps(func)
#     def wrapper(*args, **kwargs):
#         logger.info("function %s is about to be started", func)
#         try:
#             response = func(*args, **kwargs)
#         except Exception:
#             log_last_traceback()
#         else:
#             logger.info("function %s finished", func)
#             # TODO: how long it took?
#             return response
#     return wrapper
# 
# def repeater(call, args=None, kwargs=None, retries=4):
#     """
#     repeat call x-times: docker API is just awesome
# 
#     :param call: function
#     :param args: tuple, args for function
#     :param kwargs: dict, kwargs for function
#     :param retries: int, how many times we try?
#     :return: response of the call
#     """
#     args = args or ()
#     kwargs = kwargs or {}
#     t = 1.0
#     for x in range(retries):
#         try:
#             return call(*args, **kwargs)
#         except APIError as ex:
#             logger.error("query #%d: docker returned an error: %r", x, ex)
#         except Exception as ex:
#             # this may be pretty bad
#             log_last_traceback()
#             logger.error("query #%d: generic error: %r", x, ex)
#         t *= 2
#         time.sleep(t)
# 
# def humanize_time(value):
#     abbrevs = (
#         (1, "now"),
#         (2, "{seconds} seconds ago"),
#         (59, "{seconds} seconds ago"),
#         (60, "{minutes} minute ago"),
#         (119, "{minutes} minute ago"),
#         (120, "{minutes} minutes ago"),
#         (3599, "{minutes} minutes ago"),
#         (3600, "{hours} hour ago"),
#         (7199, "{hours} hour ago"),
#         (86399, "{hours} hours ago"),
#         (86400, "{days} day ago"),
#         (172799, "{days} day ago"),
#         (172800, "{days} days ago"),
#         (172800, "{days} days ago"),
#         (2591999, "{days} days ago"),
#         (2592000, "{months} month ago"),
#         (5183999, "{months} month ago"),
#         (5184000, "{months} months ago"),
#     )
#     n = datetime.now()
#     delta = n - value
#     for guard, message in abbrevs:
#         s = int(delta.total_seconds())
#         if guard >= s:
#             break
#     return message.format(seconds=delta.seconds, minutes=int(delta.seconds // 60),
#                           hours=int(delta.seconds // 3600), days=delta.days,
#                           months=int(delta.days // 30))
# 
# class OrderedSet(list):
#     def append(self, p_object):
#         if p_object in self:
#             self.remove(p_object)
#         return super().append(p_object)


# Path: tests/test_util.py
import logging
import time
import pytest
from concurrent.futures.thread import ThreadPoolExecutor
from datetime import datetime, timedelta
from sen.tui.widgets.list.common import strip_from_ansi_esc_sequences
from sen.util import _ensure_unicode, log_traceback, repeater, humanize_time, \
    OrderedSet

# -*- coding: utf-8 -*-




@pytest.mark.parametrize("inp,expected", [
    ("a", "a"),
    (b"a", "a"),
    ("\u2606", "☆"),
    (b'\xe2\x98\x86', "☆"),
])
def test_ensure_unicode(inp, expected):
    assert _ensure_unicode(inp) == expected


def test_log_traceback(caplog):
    @log_traceback
    def f():
        raise Exception()
    caplog.set_level(logging.DEBUG)
    f()
    assert caplog.records[0].message.endswith(" is about to be started")
    assert caplog.records[1].message.startswith("Traceback")
    assert caplog.records[1].message.endswith("Exception\n")


def test_log_traceback_without_tb(caplog):

    @log_traceback