I am done

This commit is contained in:
2024-10-30 22:14:35 +01:00
parent 720dc28c09
commit 40e2a747cf
36901 changed files with 5011519 additions and 0 deletions

View File

@ -0,0 +1,42 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "eb5586f8",
"metadata": {},
"outputs": [],
"source": [
"import sys\n",
"import wasabi\n",
"\n",
"wasabi.msg.warn(\"This is a test. This is only a test.\")\n",
"if sys.version_info >= (3, 7):\n",
" assert wasabi.util.supports_ansi()\n",
"\n",
"print(sys.stdout)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.7"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@ -0,0 +1,36 @@
from pathlib import Path
import subprocess
import os
import sys
import wasabi
TEST_DATA = Path(__file__).absolute().parent / "test-data"
WASABI_DIR = Path(wasabi.__file__).absolute().parent.parent
def test_jupyter():
# This runs some code in a jupyter notebook environment, but without actually
# starting up the notebook UI. Historically we once had a bug that caused crashes
# when importing wasabi in a jupyter notebook, because they replace
# sys.stdout/stderr with custom objects that aren't "real" files/ttys. So this makes
# sure that we can import and use wasabi inside a notebook without crashing.
env = dict(os.environ)
if "PYTHONPATH" in env:
env["PYTHONPATH"] = f"{WASABI_DIR}{os.pathsep}{env['PYTHONPATH']}"
else:
env["PYTHONPATH"] = str(WASABI_DIR)
subprocess.run(
[
sys.executable,
"-m",
"nbconvert",
str(TEST_DATA / "wasabi-test-notebook.ipynb"),
"--execute",
"--stdout",
"--to",
"notebook",
],
env=env,
check=True,
)

View File

@ -0,0 +1,26 @@
import pytest
from wasabi.markdown import MarkdownRenderer
def test_markdown():
md = MarkdownRenderer()
md.add(md.title(1, "Title"))
md.add("Paragraph with {}".format(md.bold("bold")))
md.add(md.list(["foo", "bar"]))
md.add(md.table([("a", "b"), ("c", "d")], ["foo", "bar"]))
md.add(md.code_block('import spacy\n\nnlp = spacy.blank("en")', "python"))
md.add(md.list(["first", "second"], numbered=True))
expected = """# Title\n\nParagraph with **bold**\n\n- foo\n- bar\n\n| foo | bar |\n| --- | --- |\n| a | b |\n| c | d |\n\n```python\nimport spacy\n\nnlp = spacy.blank("en")\n```\n\n1. first\n2. second"""
assert md.text == expected
def test_markdown_table_aligns():
md = MarkdownRenderer()
md.add(md.table([("a", "b", "c")], ["foo", "bar", "baz"], aligns=("c", "r", "l")))
expected = """| foo | bar | baz |\n| :---: | ---: | --- |\n| a | b | c |"""
assert md.text == expected
with pytest.raises(ValueError):
md.table([("a", "b", "c")], ["foo", "bar", "baz"], aligns=("c", "r"))
with pytest.raises(ValueError):
md.table([("a", "b", "c")], ["foo", "bar", "baz"], aligns=("c", "r", "l", "l"))

View File

@ -0,0 +1,236 @@
import os
import re
import time
import pytest
from wasabi.printer import Printer
from wasabi.util import MESSAGES, NO_UTF8, supports_ansi
SUPPORTS_ANSI = supports_ansi()
def test_printer():
p = Printer(no_print=True)
text = "This is a test."
good = p.good(text)
fail = p.fail(text)
warn = p.warn(text)
info = p.info(text)
assert p.text(text) == text
if SUPPORTS_ANSI and not NO_UTF8:
assert good == "\x1b[38;5;2m\u2714 {}\x1b[0m".format(text)
assert fail == "\x1b[38;5;1m\u2718 {}\x1b[0m".format(text)
assert warn == "\x1b[38;5;3m\u26a0 {}\x1b[0m".format(text)
assert info == "\x1b[38;5;4m\u2139 {}\x1b[0m".format(text)
if SUPPORTS_ANSI and NO_UTF8:
assert good == "\x1b[38;5;2m[+] {}\x1b[0m".format(text)
assert fail == "\x1b[38;5;1m[x] {}\x1b[0m".format(text)
assert warn == "\x1b[38;5;3m[!] {}\x1b[0m".format(text)
assert info == "\x1b[38;5;4m[i] {}\x1b[0m".format(text)
if not SUPPORTS_ANSI and not NO_UTF8:
assert good == "\u2714 {}".format(text)
assert fail == "\u2718 {}".format(text)
assert warn == "\u26a0 {}".format(text)
assert info == "\u2139 {}".format(text)
if not SUPPORTS_ANSI and NO_UTF8:
assert good == "[+] {}".format(text)
assert fail == "[x] {}".format(text)
assert warn == "[!] {}".format(text)
assert info == "[i] {}".format(text)
def test_printer_print():
p = Printer()
text = "This is a test."
p.good(text)
p.fail(text)
p.info(text)
p.text(text)
def test_printer_print_timestamp():
p = Printer(no_print=True, timestamp=True)
result = p.info("Hello world")
matches = re.match("^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}", result)
assert matches
def test_printer_no_pretty():
p = Printer(no_print=True, pretty=False)
text = "This is a test."
assert p.good(text) == text
assert p.fail(text) == text
assert p.warn(text) == text
assert p.info(text) == text
assert p.text(text) == text
def test_printer_custom():
colors = {"yellow": 220, "purple": 99}
icons = {"warn": "\u26a0\ufe0f", "question": "?"}
p = Printer(no_print=True, colors=colors, icons=icons)
text = "This is a test."
purple_question = p.text(text, color="purple", icon="question")
warning = p.warn(text)
if SUPPORTS_ANSI and not NO_UTF8:
assert purple_question == "\x1b[38;5;99m? {}\x1b[0m".format(text)
assert warning == "\x1b[38;5;3m\u26a0\ufe0f {}\x1b[0m".format(text)
if SUPPORTS_ANSI and NO_UTF8:
assert purple_question == "\x1b[38;5;99m? {}\x1b[0m".format(text)
assert warning == "\x1b[38;5;3m?? {}\x1b[0m".format(text)
if not SUPPORTS_ANSI and not NO_UTF8:
assert purple_question == "? {}".format(text)
assert warning == "\u26a0\ufe0f {}".format(text)
if not SUPPORTS_ANSI and NO_UTF8:
assert purple_question == "? {}".format(text)
assert warning == "?? {}".format(text)
def test_color_as_int():
p = Printer(no_print=True)
text = "This is a text."
result = p.text(text, color=220)
if SUPPORTS_ANSI:
assert result == "\x1b[38;5;220mThis is a text.\x1b[0m"
else:
assert result == "This is a text."
def test_bg_color():
p = Printer(no_print=True)
text = "This is a text."
result = p.text(text, bg_color="red")
print(result)
if SUPPORTS_ANSI:
assert result == "\x1b[48;5;1mThis is a text.\x1b[0m"
else:
assert result == "This is a text."
def test_bg_color_as_int():
p = Printer(no_print=True)
text = "This is a text."
result = p.text(text, bg_color=220)
print(result)
if SUPPORTS_ANSI:
assert result == "\x1b[48;5;220mThis is a text.\x1b[0m"
else:
assert result == "This is a text."
def test_color_and_bc_color():
p = Printer(no_print=True)
text = "This is a text."
result = p.text(text, color="green", bg_color="yellow")
print(result)
if SUPPORTS_ANSI:
assert result == "\x1b[38;5;2;48;5;3mThis is a text.\x1b[0m"
else:
assert result == "This is a text."
def test_printer_counts():
p = Printer()
text = "This is a test."
for i in range(2):
p.good(text)
for i in range(1):
p.fail(text)
for i in range(4):
p.warn(text)
assert p.counts[MESSAGES.GOOD] == 2
assert p.counts[MESSAGES.FAIL] == 1
assert p.counts[MESSAGES.WARN] == 4
def test_printer_spaced():
p = Printer(no_print=True, pretty=False)
text = "This is a test."
assert p.good(text) == text
assert p.good(text, spaced=True) == "\n{}\n".format(text)
def test_printer_divider():
p = Printer(line_max=20, no_print=True)
p.divider() == "\x1b[1m\n================\x1b[0m"
p.divider("test") == "\x1b[1m\n====== test ======\x1b[0m"
p.divider("test", char="*") == "\x1b[1m\n****** test ******\x1b[0m"
assert (
p.divider("This is a very long text, it is very long")
== "\x1b[1m\n This is a very long text, it is very long \x1b[0m"
)
with pytest.raises(ValueError):
p.divider("test", char="~.")
@pytest.mark.parametrize("hide_animation", [False, True])
def test_printer_loading(hide_animation):
p = Printer(hide_animation=hide_animation)
print("\n")
with p.loading("Loading..."):
time.sleep(1)
p.good("Success!")
with p.loading("Something else..."):
time.sleep(2)
p.good("Yo!")
with p.loading("Loading..."):
time.sleep(1)
p.good("Success!")
def test_printer_loading_raises_exception():
def loading_with_exception():
p = Printer()
print("\n")
with p.loading():
raise Exception("This is an error.")
with pytest.raises(Exception):
loading_with_exception()
def test_printer_loading_no_print():
p = Printer(no_print=True)
with p.loading("Loading..."):
time.sleep(1)
p.good("Success!")
def test_printer_log_friendly():
text = "This is a test."
ENV_LOG_FRIENDLY = "WASABI_LOG_FRIENDLY"
os.environ[ENV_LOG_FRIENDLY] = "True"
p = Printer(no_print=True)
assert p.good(text) in ("\u2714 This is a test.", "[+] This is a test.")
del os.environ[ENV_LOG_FRIENDLY]
def test_printer_log_friendly_prefix():
text = "This is a test."
ENV_LOG_FRIENDLY = "CUSTOM_LOG_FRIENDLY"
os.environ[ENV_LOG_FRIENDLY] = "True"
p = Printer(no_print=True, env_prefix="CUSTOM")
assert p.good(text) in ("\u2714 This is a test.", "[+] This is a test.")
print(p.good(text))
del os.environ[ENV_LOG_FRIENDLY]
@pytest.mark.skip(reason="Now seems to raise TypeError: readonly attribute?")
def test_printer_none_encoding(monkeypatch):
"""Test that printer works even if sys.stdout.encoding is set to None. This
previously caused a very confusing error."""
monkeypatch.setattr("sys.stdout.encoding", None)
p = Printer() # noqa: F841
def test_printer_no_print_raise_on_exit():
"""Test that the printer raises if a non-zero exit code is provided, even
if no_print is set to True."""
err = "This is an error."
p = Printer(no_print=True, pretty=False)
with pytest.raises(SystemExit) as e:
p.fail(err, exits=True)
assert str(e.value).strip()[-len(err) :] == err

View File

@ -0,0 +1,421 @@
import os
import pytest
from wasabi.tables import row, table
from wasabi.util import supports_ansi
SUPPORTS_ANSI = supports_ansi()
@pytest.fixture()
def data():
return [("Hello", "World", "12344342"), ("This is a test", "World", "1234")]
@pytest.fixture()
def header():
return ["COL A", "COL B", "COL 3"]
@pytest.fixture()
def footer():
return ["", "", "2030203.00"]
@pytest.fixture()
def fg_colors():
return ["", "yellow", "87"]
@pytest.fixture()
def bg_colors():
return ["green", "23", ""]
def test_table_default(data):
result = table(data)
assert (
result
== "\nHello World 12344342\nThis is a test World 1234 \n"
)
def test_table_header(data, header):
result = table(data, header=header)
assert (
result
== "\nCOL A COL B COL 3 \nHello World 12344342\nThis is a test World 1234 \n"
)
def test_table_header_footer_divider(data, header, footer):
result = table(data, header=header, footer=footer, divider=True)
assert (
result
== "\nCOL A COL B COL 3 \n-------------- ----- ----------\nHello World 12344342 \nThis is a test World 1234 \n-------------- ----- ----------\n 2030203.00\n"
)
def test_table_aligns(data):
result = table(data, aligns=("r", "c", "l"))
assert (
result
== "\n Hello World 12344342\nThis is a test World 1234 \n"
)
def test_table_aligns_single(data):
result = table(data, aligns="r")
assert (
result
== "\n Hello World 12344342\nThis is a test World 1234\n"
)
def test_table_widths():
data = [("a", "bb", "ccc"), ("d", "ee", "fff")]
widths = (5, 2, 10)
result = table(data, widths=widths)
assert result == "\na bb ccc \nd ee fff \n"
def test_row_single_widths():
data = ("a", "bb", "ccc")
result = row(data, widths=10)
assert result == "a bb ccc "
def test_table_multiline(header):
data = [
("hello", ["foo", "bar", "baz"], "world"),
("hello", "world", ["world 1", "world 2"]),
]
result = table(data, header=header, divider=True, multiline=True)
assert (
result
== "\nCOL A COL B COL 3 \n----- ----- -------\nhello foo world \n bar \n baz \n \nhello world world 1\n world 2\n"
)
def test_row_fg_colors(fg_colors):
result = row(("Hello", "World", "12344342"), fg_colors=fg_colors)
if SUPPORTS_ANSI:
assert (
result == "Hello \x1b[38;5;3mWorld\x1b[0m \x1b[38;5;87m12344342\x1b[0m"
)
else:
assert result == "Hello World 12344342"
def test_row_bg_colors(bg_colors):
result = row(("Hello", "World", "12344342"), bg_colors=bg_colors)
if SUPPORTS_ANSI:
assert (
result == "\x1b[48;5;2mHello\x1b[0m \x1b[48;5;23mWorld\x1b[0m 12344342"
)
else:
assert result == "Hello World 12344342"
def test_row_fg_colors_and_bg_colors(fg_colors, bg_colors):
result = row(
("Hello", "World", "12344342"), fg_colors=fg_colors, bg_colors=bg_colors
)
if SUPPORTS_ANSI:
assert (
result
== "\x1b[48;5;2mHello\x1b[0m \x1b[38;5;3;48;5;23mWorld\x1b[0m \x1b[38;5;87m12344342\x1b[0m"
)
else:
assert result == "Hello World 12344342"
def test_row_fg_colors_and_bg_colors_log_friendly(fg_colors, bg_colors):
ENV_LOG_FRIENDLY = "WASABI_LOG_FRIENDLY"
os.environ[ENV_LOG_FRIENDLY] = "True"
result = row(
("Hello", "World", "12344342"), fg_colors=fg_colors, bg_colors=bg_colors
)
assert result == "Hello World 12344342"
del os.environ[ENV_LOG_FRIENDLY]
def test_row_fg_colors_and_bg_colors_log_friendly_prefix(fg_colors, bg_colors):
ENV_LOG_FRIENDLY = "CUSTOM_LOG_FRIENDLY"
os.environ[ENV_LOG_FRIENDLY] = "True"
result = row(
("Hello", "World", "12344342"),
fg_colors=fg_colors,
bg_colors=bg_colors,
env_prefix="CUSTOM",
)
assert result == "Hello World 12344342"
del os.environ[ENV_LOG_FRIENDLY]
def test_row_fg_colors_and_bg_colors_supports_ansi_false(fg_colors, bg_colors):
os.environ["ANSI_COLORS_DISABLED"] = "True"
result = row(
("Hello", "World", "12344342"), fg_colors=fg_colors, bg_colors=bg_colors
)
assert result == "Hello World 12344342"
del os.environ["ANSI_COLORS_DISABLED"]
def test_colors_whole_table_with_automatic_widths(
data, header, footer, fg_colors, bg_colors
):
result = table(
data,
header=header,
footer=footer,
divider=True,
fg_colors=fg_colors,
bg_colors=bg_colors,
)
if SUPPORTS_ANSI:
assert (
result
== "\n\x1b[48;5;2mCOL A \x1b[0m \x1b[38;5;3;48;5;23mCOL B\x1b[0m \x1b[38;5;87mCOL 3 \x1b[0m\n\x1b[48;5;2m--------------\x1b[0m \x1b[38;5;3;48;5;23m-----\x1b[0m \x1b[38;5;87m----------\x1b[0m\n\x1b[48;5;2mHello \x1b[0m \x1b[38;5;3;48;5;23mWorld\x1b[0m \x1b[38;5;87m12344342 \x1b[0m\n\x1b[48;5;2mThis is a test\x1b[0m \x1b[38;5;3;48;5;23mWorld\x1b[0m \x1b[38;5;87m1234 \x1b[0m\n\x1b[48;5;2m--------------\x1b[0m \x1b[38;5;3;48;5;23m-----\x1b[0m \x1b[38;5;87m----------\x1b[0m\n\x1b[48;5;2m \x1b[0m \x1b[38;5;3;48;5;23m \x1b[0m \x1b[38;5;87m2030203.00\x1b[0m\n"
)
else:
assert (
result
== "\nCOL A COL B COL 3 \n-------------- ----- ----------\nHello World 12344342 \nThis is a test World 1234 \n-------------- ----- ----------\n 2030203.00\n"
)
def test_colors_whole_table_only_fg_colors(data, header, footer, fg_colors):
result = table(
data,
header=header,
footer=footer,
divider=True,
fg_colors=fg_colors,
)
if SUPPORTS_ANSI:
assert (
result
== "\nCOL A \x1b[38;5;3mCOL B\x1b[0m \x1b[38;5;87mCOL 3 \x1b[0m\n-------------- \x1b[38;5;3m-----\x1b[0m \x1b[38;5;87m----------\x1b[0m\nHello \x1b[38;5;3mWorld\x1b[0m \x1b[38;5;87m12344342 \x1b[0m\nThis is a test \x1b[38;5;3mWorld\x1b[0m \x1b[38;5;87m1234 \x1b[0m\n-------------- \x1b[38;5;3m-----\x1b[0m \x1b[38;5;87m----------\x1b[0m\n \x1b[38;5;3m \x1b[0m \x1b[38;5;87m2030203.00\x1b[0m\n"
)
else:
assert (
result
== "\nCOL A COL B COL 3 \n-------------- ----- ----------\nHello World 12344342 \nThis is a test World 1234 \n-------------- ----- ----------\n 2030203.00\n"
)
def test_colors_whole_table_only_bg_colors(data, header, footer, bg_colors):
result = table(
data,
header=header,
footer=footer,
divider=True,
bg_colors=bg_colors,
)
if SUPPORTS_ANSI:
assert (
result
== "\n\x1b[48;5;2mCOL A \x1b[0m \x1b[48;5;23mCOL B\x1b[0m COL 3 \n\x1b[48;5;2m--------------\x1b[0m \x1b[48;5;23m-----\x1b[0m ----------\n\x1b[48;5;2mHello \x1b[0m \x1b[48;5;23mWorld\x1b[0m 12344342 \n\x1b[48;5;2mThis is a test\x1b[0m \x1b[48;5;23mWorld\x1b[0m 1234 \n\x1b[48;5;2m--------------\x1b[0m \x1b[48;5;23m-----\x1b[0m ----------\n\x1b[48;5;2m \x1b[0m \x1b[48;5;23m \x1b[0m 2030203.00\n"
)
else:
assert (
result
== "\nCOL A COL B COL 3 \n-------------- ----- ----------\nHello World 12344342 \nThis is a test World 1234 \n-------------- ----- ----------\n 2030203.00\n"
)
def test_colors_whole_table_with_supplied_spacing(
data, header, footer, fg_colors, bg_colors
):
result = table(
data,
header=header,
footer=footer,
divider=True,
fg_colors=fg_colors,
bg_colors=bg_colors,
spacing=5,
)
if SUPPORTS_ANSI:
assert (
result
== "\n\x1b[48;5;2mCOL A \x1b[0m \x1b[38;5;3;48;5;23mCOL B\x1b[0m \x1b[38;5;87mCOL 3 \x1b[0m\n\x1b[48;5;2m--------------\x1b[0m \x1b[38;5;3;48;5;23m-----\x1b[0m \x1b[38;5;87m----------\x1b[0m\n\x1b[48;5;2mHello \x1b[0m \x1b[38;5;3;48;5;23mWorld\x1b[0m \x1b[38;5;87m12344342 \x1b[0m\n\x1b[48;5;2mThis is a test\x1b[0m \x1b[38;5;3;48;5;23mWorld\x1b[0m \x1b[38;5;87m1234 \x1b[0m\n\x1b[48;5;2m--------------\x1b[0m \x1b[38;5;3;48;5;23m-----\x1b[0m \x1b[38;5;87m----------\x1b[0m\n\x1b[48;5;2m \x1b[0m \x1b[38;5;3;48;5;23m \x1b[0m \x1b[38;5;87m2030203.00\x1b[0m\n"
)
else:
assert (
result
== "\nCOL A COL B COL 3 \n-------------- ----- ----------\nHello World 12344342 \nThis is a test World 1234 \n-------------- ----- ----------\n 2030203.00\n"
)
def test_colors_whole_table_with_supplied_widths(
data, header, footer, fg_colors, bg_colors
):
result = table(
data,
header=header,
footer=footer,
divider=True,
fg_colors=fg_colors,
bg_colors=bg_colors,
widths=(5, 2, 10),
)
if SUPPORTS_ANSI:
assert (
result
== "\n\x1b[48;5;2mCOL A\x1b[0m \x1b[38;5;3;48;5;23mCOL B\x1b[0m \x1b[38;5;87mCOL 3 \x1b[0m\n\x1b[48;5;2m-----\x1b[0m \x1b[38;5;3;48;5;23m--\x1b[0m \x1b[38;5;87m----------\x1b[0m\n\x1b[48;5;2mHello\x1b[0m \x1b[38;5;3;48;5;23mWorld\x1b[0m \x1b[38;5;87m12344342 \x1b[0m\n\x1b[48;5;2mThis is a test\x1b[0m \x1b[38;5;3;48;5;23mWorld\x1b[0m \x1b[38;5;87m1234 \x1b[0m\n\x1b[48;5;2m-----\x1b[0m \x1b[38;5;3;48;5;23m--\x1b[0m \x1b[38;5;87m----------\x1b[0m\n\x1b[48;5;2m \x1b[0m \x1b[38;5;3;48;5;23m \x1b[0m \x1b[38;5;87m2030203.00\x1b[0m\n"
)
else:
assert (
result
== "\nCOL A COL B COL 3 \n----- -- ----------\nHello World 12344342 \nThis is a test World 1234 \n----- -- ----------\n 2030203.00\n"
)
def test_colors_whole_table_with_single_alignment(
data, header, footer, fg_colors, bg_colors
):
result = table(
data,
header=header,
footer=footer,
divider=True,
fg_colors=fg_colors,
bg_colors=bg_colors,
aligns="r",
)
if SUPPORTS_ANSI:
assert (
result
== "\n\x1b[48;5;2m COL A\x1b[0m \x1b[38;5;3;48;5;23mCOL B\x1b[0m \x1b[38;5;87m COL 3\x1b[0m\n\x1b[48;5;2m--------------\x1b[0m \x1b[38;5;3;48;5;23m-----\x1b[0m \x1b[38;5;87m----------\x1b[0m\n\x1b[48;5;2m Hello\x1b[0m \x1b[38;5;3;48;5;23mWorld\x1b[0m \x1b[38;5;87m 12344342\x1b[0m\n\x1b[48;5;2mThis is a test\x1b[0m \x1b[38;5;3;48;5;23mWorld\x1b[0m \x1b[38;5;87m 1234\x1b[0m\n\x1b[48;5;2m--------------\x1b[0m \x1b[38;5;3;48;5;23m-----\x1b[0m \x1b[38;5;87m----------\x1b[0m\n\x1b[48;5;2m \x1b[0m \x1b[38;5;3;48;5;23m \x1b[0m \x1b[38;5;87m2030203.00\x1b[0m\n"
)
else:
assert (
result
== "\n COL A COL B COL 3\n-------------- ----- ----------\n Hello World 12344342\nThis is a test World 1234\n-------------- ----- ----------\n 2030203.00\n"
)
def test_colors_whole_table_with_multiple_alignment(
data, header, footer, fg_colors, bg_colors
):
result = table(
data,
header=header,
footer=footer,
divider=True,
fg_colors=fg_colors,
bg_colors=bg_colors,
aligns=("c", "r", "l"),
)
if SUPPORTS_ANSI:
assert (
result
== "\n\x1b[48;5;2m COL A \x1b[0m \x1b[38;5;3;48;5;23mCOL B\x1b[0m \x1b[38;5;87mCOL 3 \x1b[0m\n\x1b[48;5;2m--------------\x1b[0m \x1b[38;5;3;48;5;23m-----\x1b[0m \x1b[38;5;87m----------\x1b[0m\n\x1b[48;5;2m Hello \x1b[0m \x1b[38;5;3;48;5;23mWorld\x1b[0m \x1b[38;5;87m12344342 \x1b[0m\n\x1b[48;5;2mThis is a test\x1b[0m \x1b[38;5;3;48;5;23mWorld\x1b[0m \x1b[38;5;87m1234 \x1b[0m\n\x1b[48;5;2m--------------\x1b[0m \x1b[38;5;3;48;5;23m-----\x1b[0m \x1b[38;5;87m----------\x1b[0m\n\x1b[48;5;2m \x1b[0m \x1b[38;5;3;48;5;23m \x1b[0m \x1b[38;5;87m2030203.00\x1b[0m\n"
)
else:
assert (
result
== "\n COL A COL B COL 3 \n-------------- ----- ----------\n Hello World 12344342 \nThis is a test World 1234 \n-------------- ----- ----------\n 2030203.00\n"
)
def test_colors_whole_table_with_multiline(data, header, footer, fg_colors, bg_colors):
result = table(
data=((["Charles", "Quinton", "Murphy"], "my", "brother"), ("1", "2", "3")),
fg_colors=fg_colors,
bg_colors=bg_colors,
multiline=True,
)
if SUPPORTS_ANSI:
assert (
result
== "\n\x1b[48;5;2mCharles\x1b[0m \x1b[38;5;3;48;5;23mmy\x1b[0m \x1b[38;5;87mbrother\x1b[0m\n\x1b[48;5;2mQuinton\x1b[0m \x1b[38;5;3;48;5;23m \x1b[0m \x1b[38;5;87m \x1b[0m\n\x1b[48;5;2mMurphy \x1b[0m \x1b[38;5;3;48;5;23m \x1b[0m \x1b[38;5;87m \x1b[0m\n\x1b[48;5;2m \x1b[0m \x1b[38;5;3;48;5;23m \x1b[0m \x1b[38;5;87m \x1b[0m\n\x1b[48;5;2m1 \x1b[0m \x1b[38;5;3;48;5;23m2 \x1b[0m \x1b[38;5;87m3 \x1b[0m\n"
)
else:
assert (
result
== "\nCharles my brother\nQuinton \nMurphy \n \n1 2 3 \n"
)
def test_colors_whole_table_log_friendly(data, header, footer, fg_colors, bg_colors):
ENV_LOG_FRIENDLY = "WASABI_LOG_FRIENDLY"
os.environ[ENV_LOG_FRIENDLY] = "True"
result = table(
data,
header=header,
footer=footer,
divider=True,
fg_colors=fg_colors,
bg_colors=bg_colors,
)
assert (
result
== "\nCOL A COL B COL 3 \n-------------- ----- ----------\nHello World 12344342 \nThis is a test World 1234 \n-------------- ----- ----------\n 2030203.00\n"
)
del os.environ[ENV_LOG_FRIENDLY]
def test_colors_whole_table_log_friendly_prefix(
data, header, footer, fg_colors, bg_colors
):
ENV_LOG_FRIENDLY = "CUSTOM_LOG_FRIENDLY"
os.environ[ENV_LOG_FRIENDLY] = "True"
result = table(
data,
header=header,
footer=footer,
divider=True,
fg_colors=fg_colors,
bg_colors=bg_colors,
env_prefix="CUSTOM",
)
assert (
result
== "\nCOL A COL B COL 3 \n-------------- ----- ----------\nHello World 12344342 \nThis is a test World 1234 \n-------------- ----- ----------\n 2030203.00\n"
)
del os.environ[ENV_LOG_FRIENDLY]
def test_colors_whole_table_supports_ansi_false(
data, header, footer, fg_colors, bg_colors
):
os.environ["ANSI_COLORS_DISABLED"] = "True"
result = table(
data,
header=header,
footer=footer,
divider=True,
fg_colors=fg_colors,
bg_colors=bg_colors,
)
assert (
result
== "\nCOL A COL B COL 3 \n-------------- ----- ----------\nHello World 12344342 \nThis is a test World 1234 \n-------------- ----- ----------\n 2030203.00\n"
)
del os.environ["ANSI_COLORS_DISABLED"]
def test_colors_whole_table_color_values(data, header, footer, fg_colors, bg_colors):
result = table(
data,
header=header,
footer=footer,
divider=True,
fg_colors=fg_colors,
bg_colors=bg_colors,
color_values={"yellow": 11},
)
if SUPPORTS_ANSI:
assert (
result
== "\n\x1b[48;5;2mCOL A \x1b[0m \x1b[38;5;11;48;5;23mCOL B\x1b[0m \x1b[38;5;87mCOL 3 \x1b[0m\n\x1b[48;5;2m--------------\x1b[0m \x1b[38;5;11;48;5;23m-----\x1b[0m \x1b[38;5;87m----------\x1b[0m\n\x1b[48;5;2mHello \x1b[0m \x1b[38;5;11;48;5;23mWorld\x1b[0m \x1b[38;5;87m12344342 \x1b[0m\n\x1b[48;5;2mThis is a test\x1b[0m \x1b[38;5;11;48;5;23mWorld\x1b[0m \x1b[38;5;87m1234 \x1b[0m\n\x1b[48;5;2m--------------\x1b[0m \x1b[38;5;11;48;5;23m-----\x1b[0m \x1b[38;5;87m----------\x1b[0m\n\x1b[48;5;2m \x1b[0m \x1b[38;5;11;48;5;23m \x1b[0m \x1b[38;5;87m2030203.00\x1b[0m\n"
)
else:
assert (
result
== "\nCOL A COL B COL 3 \n-------------- ----- ----------\nHello World 12344342 \nThis is a test World 1234 \n-------------- ----- ----------\n 2030203.00\n"
)

View File

@ -0,0 +1,66 @@
import traceback
import pytest
from wasabi.traceback_printer import TracebackPrinter
@pytest.fixture
def tb():
return traceback.extract_stack()
def test_traceback_printer(tb):
tbp = TracebackPrinter(tb_base="wasabi")
msg = tbp("Hello world", "This is a test", tb=tb)
print(msg)
def test_traceback_printer_highlight(tb):
tbp = TracebackPrinter(tb_base="wasabi")
msg = tbp("Hello world", "This is a test", tb=tb, highlight="kwargs")
print(msg)
def test_traceback_printer_custom_colors(tb):
tbp = TracebackPrinter(
tb_base="wasabi", color_error="blue", color_highlight="green", color_tb="yellow"
)
msg = tbp("Hello world", "This is a test", tb=tb, highlight="kwargs")
print(msg)
def test_traceback_printer_only_title(tb):
tbp = TracebackPrinter(tb_base="wasabi")
msg = tbp("Hello world", tb=tb)
print(msg)
def test_traceback_dot_relative_path_tb_base(tb):
tbp = TracebackPrinter(tb_base=".")
msg = tbp("Hello world", tb=tb)
print(msg)
def test_traceback_tb_base_none(tb):
tbp = TracebackPrinter()
msg = tbp("Hello world", tb=tb)
print(msg)
def test_traceback_printer_no_tb():
tbp = TracebackPrinter(tb_base="wasabi")
msg = tbp("Hello world", "This is a test")
print(msg)
def test_traceback_printer_custom_tb_range():
tbp = TracebackPrinter(tb_range_start=-10, tb_range_end=-3)
msg = tbp("Hello world", "This is a test")
print(msg)
def test_traceback_printer_custom_tb_range_start():
tbp = TracebackPrinter(tb_range_start=-1)
msg = tbp("Hello world", "This is a test")
print(msg)

View File

@ -0,0 +1,73 @@
import pytest
from wasabi.util import color, diff_strings, format_repr, locale_escape, wrap
def test_color():
assert color("test", fg="green") == "\x1b[38;5;2mtest\x1b[0m"
assert color("test", fg=4) == "\x1b[38;5;4mtest\x1b[0m"
assert color("test", bold=True) == "\x1b[1mtest\x1b[0m"
assert color("test", fg="red", underline=True) == "\x1b[4;38;5;1mtest\x1b[0m"
assert (
color("test", fg=7, bg="red", bold=True) == "\x1b[1;38;5;7;48;5;1mtest\x1b[0m"
)
def test_wrap():
text = "Hello world, this is a test."
assert wrap(text, indent=0) == text
assert wrap(text, indent=4) == " Hello world, this is a test."
assert wrap(text, wrap_max=10, indent=0) == "Hello\nworld,\nthis is a\ntest."
assert (
wrap(text, wrap_max=5, indent=2)
== " Hello\n world,\n this\n is\n a\n test."
)
def test_format_repr():
obj = {"hello": "world", "test": 123}
formatted = format_repr(obj)
assert formatted.replace("u'", "'") in [
"{'hello': 'world', 'test': 123}",
"{'test': 123, 'hello': 'world'}",
]
formatted = format_repr(obj, max_len=10)
assert formatted.replace("u'", "'") in [
"{'hel ... 123}",
"{'tes ... rld'}",
"{'te ... rld'}",
]
formatted = format_repr(obj, max_len=10, ellipsis="[...]")
assert formatted.replace("u'", "'") in [
"{'hel [...] 123}",
"{'tes [...] rld'}",
"{'te [...] rld'}",
]
@pytest.mark.parametrize(
"text,non_ascii",
[
("abc", ["abc"]),
("\u2714 abc", ["? abc"]),
("👻", ["??", "?"]), # On Python 3 windows, this becomes "?" instead of "??"
],
)
def test_locale_escape(text, non_ascii):
result = locale_escape(text)
assert result == text or result in non_ascii
print(result)
def test_diff_strings():
a = "hello\nworld\nwide\nweb"
b = "yo\nwide\nworld\nweb"
expected = "\x1b[38;5;16;48;5;2myo\x1b[0m\n\x1b[38;5;16;48;5;2mwide\x1b[0m\n\x1b[38;5;16;48;5;1mhello\x1b[0m\nworld\n\x1b[38;5;16;48;5;1mwide\x1b[0m\nweb"
assert diff_strings(a, b) == expected
def test_diff_strings_with_symbols():
a = "hello\nworld\nwide\nweb"
b = "yo\nwide\nworld\nweb"
expected = "\x1b[38;5;16;48;5;2m+ yo\x1b[0m\n\x1b[38;5;16;48;5;2m+ wide\x1b[0m\n\x1b[38;5;16;48;5;1m- hello\x1b[0m\nworld\n\x1b[38;5;16;48;5;1m- wide\x1b[0m\nweb"
assert diff_strings(a, b, add_symbols=True) == expected