void ArgumentsTest::disallowedCharacterShort() {
    std::ostringstream out;
    Error redirectError{&out};
    Arguments args;
    args.addOption(' ', "bar");

    CORRADE_COMPARE(out.str(), "Utility::Arguments::addOption(): invalid key bar or its short variant\n");
}
void ArgumentsTest::prefixedHelpWithoutPrefix() {
    Arguments args;
    args.addArgument("file").setHelp("file", "file to read")
        .addBooleanOption('b', "binary").setHelp("binary", "read as binary")
        .addSkippedPrefix("read", "reader options")
        .addSkippedPrefix("write");

    const auto expected = R"text(Usage:
  ./app [--read-...] [--write-...] [-h|--help] [-b|--binary] [--] file

Arguments:
  file          file to read
  -h, --help    display this help message and exit
  -b, --binary  read as binary
  --read-...    reader options
                (see --read-help for details)
  --write-...   (see --write-help for details)
)text";
    CORRADE_COMPARE(args.help(), expected);
}

void ArgumentsTest::prefixedHelpWithPrefix() {
    Arguments args{"read"};
    args.addOption("behavior", "buffered").setHelp("behavior", "reader behavior")
        .addOption("buffer-size").setHelp("buffer-size", "buffer size", "SIZE");

    const auto expected = R"text(Usage:
  ./app [--read-help] [--read-behavior BEHAVIOR] [--read-buffer-size SIZE] ...

Arguments:
  ...                       main application arguments
                            (see -h or --help for details)
  --read-help               display this help message and exit
  --read-behavior BEHAVIOR  reader behavior
                            (default: buffered)
  --read-buffer-size SIZE   buffer size
)text";
    CORRADE_COMPARE(args.help(), expected);
}

void ArgumentsTest::prefixedDisallowedCalls() {
    std::ostringstream out;
    Error redirectError{&out};
    Arguments args{"reader"};
    args.addArgument("foo")
        .addNamedArgument("bar")
        .addOption('a', "baz")
        .addBooleanOption("eh")
        .setHelp("global help");

    CORRADE_COMPARE(out.str(),
        "Utility::Arguments::addArgument(): argument foo not allowed in prefixed version\n"
        "Utility::Arguments::addNamedArgument(): argument bar not allowed in prefixed version\n"
        "Utility::Arguments::addOption(): short option a not allowed in prefixed version\n"
        "Utility::Arguments::addBooleanOption(): boolean option eh not allowed in prefixed version\n"
        "Utility::Arguments::setHelp(): global help text only allowed in unprefixed version\n");
}
void ArgumentsTest::prefixedDisallowedWithPrefix() {
    std::ostringstream out;
    Error redirectError{&out};
    Arguments args;
    args.addOption("reader-flush")
        .addSkippedPrefix("reader");

    CORRADE_COMPARE(out.str(),
        "Utility::Arguments::addSkippedPrefix(): skipped prefix reader conflicts with existing keys\n");
}
void ArgumentsTest::parseMissingValue() {
    Arguments args;
    args.addOption("output");

    const char* argv[] = { "", "--output" };
    const int argc = std::extent<decltype(argv)>();

    std::ostringstream out;
    Error redirectError{&out};
    CORRADE_VERIFY(!args.tryParse(argc, argv));
    CORRADE_COMPARE(out.str(), "Missing value for command-line argument --output\n");
}