test.style
import test.style
testdoes not re-export this module, so it is reached only by importing it directly.
Terminal presentation for the test module: colour, symbols, width, and the padding helpers that keep a report’s columns lined up once escape sequences are in the text.
Colour and symbols are decided once, when this module loads, from the
environment the process actually has. Nothing else in the test module
asks whether colour is on; it calls green() and gets plain text back
when it isn’t.
Deciding whether to use colour
In order, the first of these that applies wins:
NO_COLORset to anything non-empty turns colour off, per https://no-color.org. 2.FORCE_COLORset to anything other than0turns it on, which is how CI systems that capture output but still render ANSI ask for it. 3. Standard output being a terminal turns it on, and a pipe or a file turns it off.
set_enabled() overrides the lot, for a caller that has already made
the decision itself.
Deciding whether to use Unicode
ZURI_TEST_ASCII set to anything non-empty forces the ASCII symbol set.
Otherwise the box-drawing and tick/cross characters are used everywhere
except a Windows console that is not Windows Terminal, which is the one
common environment that still renders them as mojibake.
Functions
enabled()
test.style.enabled() -> bool
Whether colour is currently being emitted.
Returns bool
set_enabled()
test.style.set_enabled(on: bool)
Forces colour on or off, overriding what the environment said.
Parameters
on(bool)
unicode()
test.style.unicode() -> bool
Whether the Unicode symbol set is in use, as opposed to the ASCII fallbacks.
Returns bool
set_unicode()
test.style.set_unicode(on: bool)
Forces the Unicode symbol set on or off.
Parameters
on(bool)
bold()
test.style.bold(text: string) -> string
Emphasis. Returns text unchanged when colour is off.
Parameters
text(string)
Returns string
dim()
test.style.dim(text: string) -> string
De-emphasis, for detail that should recede: timings, counts, the suite path above a failure.
Parameters
text(string)
Returns string
inverse()
test.style.inverse(text: string) -> string
Reserved for text that has to be found instantly on a busy screen.
Parameters
text(string)
Returns string
red()
test.style.red(text: string)
Failure. @param string text @returns string
green()
test.style.green(text: string)
Success. @param string text @returns string
yellow()
test.style.yellow(text: string)
Skipped and other deliberate non-results. @param string text @returns string
cyan()
test.style.cyan(text: string)
Structure: suite names, headings. @param string text @returns string
blue()
test.style.blue(text: string)
Todo entries and other informational notes. @param string text @returns string
magenta()
test.style.magenta(text: string)
Values in a rendered diff or failure message. @param string text @returns string
grey()
test.style.grey(text: string)
Punctuation and separators. @param string text @returns string
white()
test.style.white(text: string)
Plain foreground, used to lift a key out of dimmed surroundings. @param string text @returns string
badge()
test.style.badge(kind: string, text: string) -> string
A filled, inverted label, the way a status banner reads in a CI log.
kind is one of 'pass', 'fail', 'skip', 'todo' or 'flaky';
anything else gets the neutral grey background.
Parameters
kind(string)text(string)
Returns string
symbols()
test.style.symbols() -> dict
The symbol set in use, keyed by role.
Every entry is a single display column wide in both sets, so a layout
built on them does not shift when the ASCII fallbacks are in play. The
exception is arrow, which is two columns in ASCII.
Returns dict
strip()
test.style.strip(text: string) -> string
text with every ANSI escape sequence removed.
Parameters
text(string)
Returns string
visible_length()
test.style.visible_length(text: string) -> int
How many columns text occupies once its escape sequences are
discounted. This, not length(), is what padding and alignment have to
measure.
Parameters
text(string)
Returns int
Note: counts codepoints, so a wide CJK character or an emoji is counted as one column even though a terminal draws it as two. Test names are the only user-supplied text this is applied to.
pad_right()
test.style.pad_right(text: string, width: int, fill: ?string) -> string
Pads text on the right to width visible columns, leaving it alone
when it is already that wide or wider.
Parameters
text(string)width(int)fill(?string) — a single character,' 'by default.
Returns string
pad_left()
test.style.pad_left(text: string, width: int, fill: ?string) -> string
Pads text on the left to width visible columns, leaving it alone
when it is already that wide or wider.
Parameters
text(string)width(int)fill(?string) — a single character,' 'by default.
Returns string
truncate()
test.style.truncate(text: string, width: int) -> string
Shortens text to at most width visible columns, marking the cut with
an ellipsis. Returns text untouched when it already fits.
Parameters
text(string)width(int)
Returns string
Note: only safe on text with no escape sequences in it, since it cuts by codepoint and would leave a colour sequence unterminated. Colour the result, not the input.
rule()
test.style.rule(character: string, count: int) -> string
count copies of character.
Parameters
character(string)count(int)
Returns string
indent()
test.style.indent(depth: int) -> string
Two spaces per level, the indent every nested suite and test line in the report is built from.
Parameters
depth(int)
Returns string
width()
test.style.width() -> int
The width to lay the report out to.
Asks the terminal first, falls back to COLUMNS, and finally to a
conventional 80. Clamped to 40..120 so neither a one-column pty nor a
maximised ultrawide produces an unreadable layout.
Returns int