# Path: uqbar/strings.py
# def normalize(string: str) -> str:
#     """
#     Normalizes whitespace.
# 
#     Strips leading and trailing blank lines, dedents, and removes trailing
#     whitespace from the result.
#     """
#     string = string.replace("\t", "    ")
#     lines = string.split("\n")
#     while lines and (not lines[0] or lines[0].isspace()):
#         lines.pop(0)
#     while lines and (not lines[-1] or lines[-1].isspace()):
#         lines.pop()
#     for i, line in enumerate(lines):
#         lines[i] = line.rstrip()
#     string = "\n".join(lines)
#     string = textwrap.dedent(string)
#     return string


import io
import pytest
import uqbar.cli
import uqbar.io
from uqbar.strings import normalize
        else:
            print("Wuf.")

    def _setup_argument_parser(self, parser):
        parser.add_argument("--loud", action="store_true", help="be adamant")


class VoxAggregator(uqbar.cli.CLIAggregator):
    @property
    def cli_classes(self):
        return [MeowCLI, SquawkCLI, WoofCLI]


def test_call():
    string_io = io.StringIO()
    with uqbar.io.RedirectedStreams(string_io, string_io):
        with pytest.raises(SystemExit):
            VoxAggregator()("mammals meow --loud")
    assert normalize(string_io.getvalue()) == normalize(
        """
        MEOW!
        """
    )


def test_call_help():
    string_io = io.StringIO()
    with uqbar.io.RedirectedStreams(string_io, string_io):
        with pytest.raises(SystemExit):
            VoxAggregator()("mammals meow --help")

# Path: uqbar/strings.py
# def normalize(string: str) -> str:
#     """
#     Normalizes whitespace.
# 
#     Strips leading and trailing blank lines, dedents, and removes trailing
#     whitespace from the result.
#     """
#     string = string.replace("\t", "    ")
#     lines = string.split("\n")
#     while lines and (not lines[0] or lines[0].isspace()):
#         lines.pop(0)
#     while lines and (not lines[-1] or lines[-1].isspace()):
#         lines.pop()
#     for i, line in enumerate(lines):
#         lines[i] = line.rstrip()
#     string = "\n".join(lines)
#     string = textwrap.dedent(string)
#     return string


# Path: tests/test_cli.py
import io
import pytest
import uqbar.cli
import uqbar.io
from uqbar.strings import normalize

        else:
            print("Wuf.")

    def _setup_argument_parser(self, parser):
        parser.add_argument("--loud", action="store_true", help="be adamant")


class VoxAggregator(uqbar.cli.CLIAggregator):
    @property
    def cli_classes(self):
        return [MeowCLI, SquawkCLI, WoofCLI]


def test_call():
    string_io = io.StringIO()
    with uqbar.io.RedirectedStreams(string_io, string_io):
        with pytest.raises(SystemExit):
            VoxAggregator()("mammals meow --loud")
    assert normalize(string_io.getvalue()) == normalize(
        """
        MEOW!
        """
    )


def test_call_help():
    string_io = io.StringIO()
    with uqbar.io.RedirectedStreams(string_io, string_io):
        with pytest.raises(SystemExit):
            VoxAggregator()("mammals meow --help")

    assert normalize(string_io.getvalue()) == normalize(