* fix(repair): keep RPC progress alive * fix(daemon): propagate DB open failure to FSM and add shutdown cancellation * fix(db): classify FTS5 inverted-index errors as repairable, not transient locks * fix(daemon): clean up stale corrupt files after salvage and suppress optional readiness keys * test(db_recovery): update FTS5 classification test for new transient-lock exclusion * test(gc): add garbage collector unit tests for collection, dry-run, scheduling * test(repair): expand repair manager tests with hash-verified recovery and source ordering * fix(gc): dry-run mode no longer increments blocksDeleted/bytesReclaimed * fix(mock,mcp): add atomic bool for lock consistency, move field assignments * style: fix unnecessary-copy, dead-store, and const-refable findings from Infer * fix(daemon): increase default shutdown timeout from 15s to 120s * fix(daemon): demote non-critical warnings to info (FTS5, VACUUM, WorkCoordinator timeout) * fix(db): re-enable WAL auto-checkpoint to prevent unbounded WAL growth * test(pool): add WAL auto-checkpoint and concurrency coverage for connection pool * test(pool): add exhaustion, stats, lifecycle, and read-only connection pool tests * test(pool): add tagging, WAL journal, reuse, and busy timeout tests * test(metrics): relax session snippet assertion to tolerate stub behavior * fix(test): stabilize sanitizer triage failures * fix(build): wire version and zyp deps * fix(daemon): close TSAN race clusters * fix(test): guard optional zyp dep * fix(test): address PR review findings
441 lines
18 KiB
C++
441 lines
18 KiB
C++
#include <catch2/catch_test_macros.hpp>
|
|
#include <catch2/matchers/catch_matchers_string.hpp>
|
|
|
|
#include <filesystem>
|
|
#include <fstream>
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <yams/cli/yams_cli.h>
|
|
#include <yams/compat/unistd.h>
|
|
|
|
#include "../../common/test_helpers_catch2.h"
|
|
|
|
#ifdef _WIN32
|
|
#define WIFEXITED(x) ((x) != -1)
|
|
#define WEXITSTATUS(x) (x)
|
|
#else
|
|
#include <sys/wait.h>
|
|
#endif
|
|
|
|
using Catch::Matchers::ContainsSubstring;
|
|
|
|
namespace {
|
|
|
|
namespace fs = std::filesystem;
|
|
|
|
struct CompletionCliTestHelper {
|
|
fs::path tempDir;
|
|
std::optional<yams::test::ScopedEnvVar> configEnv;
|
|
std::optional<yams::test::ScopedEnvVar> dataEnv;
|
|
std::optional<yams::test::ScopedEnvVar> nonInteractiveEnv;
|
|
std::optional<yams::test::ScopedEnvVar> disableDaemonEnv;
|
|
|
|
CompletionCliTestHelper() {
|
|
tempDir = yams::test::make_temp_dir("yams_cli_completion_catch2_test_");
|
|
fs::create_directories(tempDir / "data");
|
|
|
|
{
|
|
std::ofstream cfg(tempDir / "config.toml");
|
|
cfg << "[core]\n";
|
|
cfg << "data_dir = \"" << (tempDir / "data").string() << "\"\n";
|
|
}
|
|
|
|
configEnv.emplace("YAMS_CONFIG", (tempDir / "config.toml").string());
|
|
dataEnv.emplace("YAMS_DATA_DIR", (tempDir / "data").string());
|
|
nonInteractiveEnv.emplace(std::string("YAMS_NON_INTERACTIVE"),
|
|
std::optional<std::string>("1"));
|
|
disableDaemonEnv.emplace(std::string("YAMS_CLI_DISABLE_DAEMON_AUTOSTART"),
|
|
std::optional<std::string>("1"));
|
|
}
|
|
|
|
~CompletionCliTestHelper() {
|
|
configEnv.reset();
|
|
dataEnv.reset();
|
|
nonInteractiveEnv.reset();
|
|
disableDaemonEnv.reset();
|
|
|
|
std::error_code ec;
|
|
fs::remove_all(tempDir, ec);
|
|
}
|
|
|
|
int runCommand(const std::vector<std::string>& args) {
|
|
auto cli = std::make_unique<yams::cli::YamsCLI>();
|
|
std::vector<char*> argv;
|
|
argv.reserve(args.size());
|
|
for (const auto& arg : args) {
|
|
argv.push_back(const_cast<char*>(arg.c_str()));
|
|
}
|
|
return cli->run(static_cast<int>(argv.size()), argv.data());
|
|
}
|
|
};
|
|
|
|
class CaptureStdout {
|
|
public:
|
|
CaptureStdout() : oldCout_(std::cout.rdbuf(buffer_.rdbuf())) {}
|
|
~CaptureStdout() { std::cout.rdbuf(oldCout_); }
|
|
|
|
std::string str() const { return buffer_.str(); }
|
|
|
|
CaptureStdout(const CaptureStdout&) = delete;
|
|
CaptureStdout& operator=(const CaptureStdout&) = delete;
|
|
|
|
private:
|
|
std::ostringstream buffer_;
|
|
std::streambuf* oldCout_;
|
|
};
|
|
|
|
std::string lineContaining(const std::string& text, std::string_view needle) {
|
|
const auto pos = text.find(needle);
|
|
if (pos == std::string::npos) {
|
|
return {};
|
|
}
|
|
const auto lineEnd = text.find('\n', pos);
|
|
return text.substr(pos, lineEnd == std::string::npos ? std::string::npos : lineEnd - pos);
|
|
}
|
|
|
|
std::string stripCoverageProfilingDiagnostics(const std::string& text) {
|
|
std::istringstream input(text);
|
|
std::ostringstream filtered;
|
|
std::string line;
|
|
while (std::getline(input, line)) {
|
|
if (line.rfind("profiling: ", 0) == 0) {
|
|
continue;
|
|
}
|
|
filtered << line;
|
|
if (!input.eof()) {
|
|
filtered << '\n';
|
|
}
|
|
}
|
|
return filtered.str();
|
|
}
|
|
|
|
auto findBuiltYamsCli() -> fs::path {
|
|
std::vector<fs::path> candidates;
|
|
|
|
if (const char* buildRoot = std::getenv("MESON_BUILD_ROOT")) {
|
|
candidates.emplace_back(fs::path(buildRoot) / "tools" / "yams-cli" / "yams-cli");
|
|
}
|
|
|
|
std::vector<fs::path> bases;
|
|
if (const char* sourceRoot = std::getenv("MESON_SOURCE_ROOT")) {
|
|
bases.emplace_back(sourceRoot);
|
|
}
|
|
|
|
std::error_code ec;
|
|
auto cwd = fs::current_path(ec);
|
|
if (!ec) {
|
|
bases.push_back(cwd);
|
|
if (cwd.has_parent_path()) {
|
|
bases.push_back(cwd.parent_path());
|
|
}
|
|
if (cwd.has_parent_path() && cwd.parent_path().has_parent_path()) {
|
|
bases.push_back(cwd.parent_path().parent_path());
|
|
}
|
|
}
|
|
|
|
const std::vector<fs::path> suffixes = {
|
|
fs::path("tools") / "yams-cli" / "yams-cli",
|
|
fs::path("builddir-local") / "tools" / "yams-cli" / "yams-cli",
|
|
fs::path("builddir-asan-local") / "tools" / "yams-cli" / "yams-cli",
|
|
fs::path("builddir-ubsan-local") / "tools" / "yams-cli" / "yams-cli",
|
|
fs::path("builddir-tsan-local") / "tools" / "yams-cli" / "yams-cli",
|
|
fs::path("builddir-nosan-local") / "tools" / "yams-cli" / "yams-cli",
|
|
fs::path("builddir") / "tools" / "yams-cli" / "yams-cli",
|
|
fs::path("builddir-asan") / "tools" / "yams-cli" / "yams-cli",
|
|
fs::path("builddir-ubsan") / "tools" / "yams-cli" / "yams-cli",
|
|
fs::path("builddir-tsan") / "tools" / "yams-cli" / "yams-cli",
|
|
fs::path("builddir-nosan") / "tools" / "yams-cli" / "yams-cli",
|
|
fs::path("build") / "asan" / "tools" / "yams-cli" / "yams-cli",
|
|
fs::path("build") / "coverage" / "tools" / "yams-cli" / "yams-cli",
|
|
fs::path("build") / "release" / "tools" / "yams-cli" / "yams-cli",
|
|
fs::path("build") / "debug" / "tools" / "yams-cli" / "yams-cli",
|
|
};
|
|
|
|
for (const auto& base : bases) {
|
|
for (const auto& suffix : suffixes) {
|
|
candidates.push_back(base / suffix);
|
|
}
|
|
}
|
|
|
|
for (const auto& candidate : candidates) {
|
|
if (fs::exists(candidate)) {
|
|
return candidate;
|
|
}
|
|
}
|
|
return {};
|
|
}
|
|
|
|
} // namespace
|
|
|
|
TEST_CASE("CompletionCommand - bash script includes registered top-level commands",
|
|
"[cli][completion][catch2]") {
|
|
CompletionCliTestHelper helper;
|
|
CaptureStdout capture;
|
|
|
|
const int rc = helper.runCommand({"yams", "completion", "bash"});
|
|
const std::string output = capture.str();
|
|
|
|
REQUIRE((rc == 0));
|
|
CHECK((output.rfind("#!/bin/bash\n", 0) == 0));
|
|
CHECK((output.find("Configuration successfully migrated") == std::string::npos));
|
|
CHECK_THAT(output, ContainsSubstring("'restore'"));
|
|
CHECK_THAT(output, ContainsSubstring("'grep'"));
|
|
CHECK_THAT(output, ContainsSubstring("'status'"));
|
|
CHECK_THAT(output, ContainsSubstring("'daemon'"));
|
|
CHECK_THAT(output, ContainsSubstring("'doctor'"));
|
|
CHECK_THAT(output, ContainsSubstring("'graph'"));
|
|
CHECK_THAT(output, ContainsSubstring("'diff'"));
|
|
}
|
|
|
|
TEST_CASE("CompletionCommand - bash status and stats use current flags",
|
|
"[cli][completion][catch2]") {
|
|
CompletionCliTestHelper helper;
|
|
CaptureStdout capture;
|
|
|
|
const int rc = helper.runCommand({"yams", "completion", "bash"});
|
|
const std::string output = capture.str();
|
|
|
|
REQUIRE((rc == 0));
|
|
const std::string statusLine = lineContaining(output, "local status_flags=");
|
|
REQUIRE_FALSE(statusLine.empty());
|
|
|
|
CHECK_THAT(statusLine, ContainsSubstring("--no-physical"));
|
|
CHECK_THAT(statusLine, ContainsSubstring("--corpus"));
|
|
CHECK((statusLine.find("--format") == std::string::npos));
|
|
CHECK_THAT(output, ContainsSubstring("status|stats)"));
|
|
}
|
|
|
|
TEST_CASE("CompletionCommand - bash completes nested subcommands from command tree",
|
|
"[cli][completion][catch2]") {
|
|
#ifdef _WIN32
|
|
SKIP("bash nested completion smoke test requires Unix shell support");
|
|
#else
|
|
const fs::path yamsCli = findBuiltYamsCli();
|
|
REQUIRE_FALSE(yamsCli.empty());
|
|
|
|
const fs::path tempDir = yams::test::make_temp_dir("yams_bash_completion_tree_");
|
|
const fs::path dataDir = tempDir / "data";
|
|
fs::create_directories(dataDir);
|
|
const fs::path script = tempDir / "yams.bash";
|
|
const fs::path out = tempDir / "bash-tree.out";
|
|
|
|
const std::string cmd =
|
|
"env YAMS_CONFIG='" + (tempDir / "missing-config.toml").string() + "' YAMS_DATA_DIR='" +
|
|
dataDir.string() +
|
|
"' YAMS_NON_INTERACTIVE=1 YAMS_CLI_DISABLE_DAEMON_AUTOSTART=1 bash -lc "
|
|
"'set -euo pipefail; \"" +
|
|
yamsCli.string() + "\" completion bash > \"" + script.string() + "\"; source \"" +
|
|
script.string() +
|
|
"\"; COMP_WORDS=(yams config em); COMP_CWORD=2; _yams_completion; printf \"CONFIG:%s\\n\" "
|
|
"\"${COMPREPLY[*]}\"; COMP_WORDS=(yams plugin trust re); COMP_CWORD=3; "
|
|
"_yams_completion; printf \"PLUGIN:%s\\n\" \"${COMPREPLY[*]}\"; "
|
|
"COMP_WORDS=(yams daemon start \"\"); COMP_CWORD=3; _yams_completion; printf "
|
|
"\"START:%s\\n\" \"${COMPREPLY[*]}\"; "
|
|
"COMP_WORDS=(yams daemon start --log-level \"\"); COMP_CWORD=4; _yams_completion; "
|
|
"printf \"LOGLEVEL:%s\\n\" \"${COMPREPLY[*]}\"; "
|
|
"COMP_WORDS=(yams config search path-tree enable --mode \"\"); COMP_CWORD=6; "
|
|
"_yams_completion; "
|
|
"printf \"PATHTREE:%s\\n\" \"${COMPREPLY[*]}\"; "
|
|
"COMP_WORDS=(yams plugin trust list \"\"); COMP_CWORD=4; _yams_completion; printf "
|
|
"\"TRUSTLIST:%s\\n\" \"${COMPREPLY[*]}\"; "
|
|
"COMP_WORDS=(yams plugins trust list \"\"); COMP_CWORD=4; _yams_completion; printf "
|
|
"\"PLUGINSALIAS:%s\\n\" \"${COMPREPLY[*]}\"' > '" +
|
|
out.string() + "'";
|
|
|
|
const int rc = std::system(cmd.c_str());
|
|
REQUIRE(WIFEXITED(rc));
|
|
REQUIRE((WEXITSTATUS(rc) == 0));
|
|
|
|
std::ifstream input(out);
|
|
REQUIRE(input.good());
|
|
std::string configLine;
|
|
std::string pluginLine;
|
|
std::string daemonStartLine;
|
|
std::string logLevelLine;
|
|
std::string pathTreeLine;
|
|
std::string pluginTrustListLine;
|
|
std::string pluginsAliasLine;
|
|
std::getline(input, configLine);
|
|
std::getline(input, pluginLine);
|
|
std::getline(input, daemonStartLine);
|
|
std::getline(input, logLevelLine);
|
|
std::getline(input, pathTreeLine);
|
|
std::getline(input, pluginTrustListLine);
|
|
std::getline(input, pluginsAliasLine);
|
|
|
|
CHECK_THAT(configLine, ContainsSubstring("CONFIG:embeddings"));
|
|
CHECK_THAT(pluginLine, ContainsSubstring("PLUGIN:remove"));
|
|
CHECK_THAT(pluginLine, ContainsSubstring("reset"));
|
|
CHECK_THAT(daemonStartLine, ContainsSubstring("START:--socket"));
|
|
CHECK_THAT(daemonStartLine, ContainsSubstring("--foreground"));
|
|
CHECK_THAT(daemonStartLine, ContainsSubstring("--daemon-binary"));
|
|
CHECK_THAT(logLevelLine, ContainsSubstring("LOGLEVEL:trace"));
|
|
CHECK_THAT(logLevelLine, ContainsSubstring("debug"));
|
|
CHECK_THAT(logLevelLine, ContainsSubstring("error"));
|
|
CHECK_THAT(pathTreeLine, ContainsSubstring("PATHTREE:fallback"));
|
|
CHECK_THAT(pathTreeLine, ContainsSubstring("preferred"));
|
|
CHECK_THAT(pluginTrustListLine, ContainsSubstring("TRUSTLIST:--details"));
|
|
CHECK_THAT(pluginsAliasLine, ContainsSubstring("PLUGINSALIAS:--details"));
|
|
|
|
std::error_code ec;
|
|
fs::remove_all(tempDir, ec);
|
|
#endif
|
|
}
|
|
|
|
TEST_CASE("CompletionCommand - zsh and fish status aliases no longer advertise format",
|
|
"[cli][completion][catch2]") {
|
|
CompletionCliTestHelper helper;
|
|
|
|
CaptureStdout zshCapture;
|
|
const int zshRc = helper.runCommand({"yams", "completion", "zsh"});
|
|
const std::string zshOutput = zshCapture.str();
|
|
REQUIRE((zshRc == 0));
|
|
CHECK((zshOutput.rfind("#compdef yams\n", 0) == 0));
|
|
CHECK((zshOutput.find("Configuration successfully migrated") == std::string::npos));
|
|
CHECK_THAT(zshOutput, ContainsSubstring("status|stats"));
|
|
CHECK_THAT(zshOutput, ContainsSubstring("--no-physical"));
|
|
CHECK_THAT(zshOutput, ContainsSubstring("--corpus"));
|
|
CHECK((zshOutput.find("--format[Output format]:format:(text json)") == std::string::npos));
|
|
CHECK_THAT(zshOutput, ContainsSubstring("_yams_subcommand_names_for()"));
|
|
CHECK_THAT(zshOutput, ContainsSubstring("command_path=\"$(_yams_command_path $CURRENT)\""));
|
|
CHECK_THAT(zshOutput, ContainsSubstring("compdef _yams yams"));
|
|
CHECK_THAT(zshOutput, ContainsSubstring("'config')"));
|
|
CHECK_THAT(zshOutput, ContainsSubstring("'embeddings:Manage embedding configuration'"));
|
|
CHECK_THAT(zshOutput, ContainsSubstring("'plugin trust')"));
|
|
CHECK_THAT(zshOutput, ContainsSubstring("'remove:Remove a trusted plugin path'"));
|
|
CHECK((zshOutput.find("'plugins trust')") == std::string::npos));
|
|
CHECK_THAT(zshOutput, ContainsSubstring("'daemon start')"));
|
|
CHECK_THAT(zshOutput, ContainsSubstring("'--socket:Socket path for daemon communication'"));
|
|
CHECK_THAT(zshOutput, ContainsSubstring("'plugin trust list')"));
|
|
CHECK_THAT(zshOutput,
|
|
ContainsSubstring(
|
|
"'--details:Show trust file, defaults, strict mode, and effective roots'"));
|
|
CHECK_THAT(zshOutput, ContainsSubstring("'daemon start:--log-level')"));
|
|
CHECK_THAT(zshOutput, ContainsSubstring("'trace' 'debug' 'info' 'warn' 'error'"));
|
|
CHECK_THAT(zshOutput, ContainsSubstring("'config search path-tree enable:--mode')"));
|
|
CHECK_THAT(zshOutput, ContainsSubstring("'fallback' 'preferred'"));
|
|
|
|
CaptureStdout fishCapture;
|
|
const int fishRc = helper.runCommand({"yams", "completion", "fish"});
|
|
const std::string fishOutput = fishCapture.str();
|
|
REQUIRE((fishRc == 0));
|
|
CHECK_THAT(fishOutput,
|
|
ContainsSubstring("__fish_yams_path_is status; or __fish_yams_path_is stats"));
|
|
CHECK_THAT(fishOutput, ContainsSubstring("-l no-physical"));
|
|
CHECK_THAT(fishOutput, ContainsSubstring("-l corpus"));
|
|
CHECK((fishOutput.find("__fish_yams_path_is stats' -l format") == std::string::npos));
|
|
CHECK_THAT(fishOutput, ContainsSubstring("case 'config'"));
|
|
CHECK_THAT(fishOutput, ContainsSubstring("'embeddings' 'Manage embedding configuration'"));
|
|
CHECK_THAT(fishOutput, ContainsSubstring("case 'plugin trust'"));
|
|
CHECK_THAT(fishOutput, ContainsSubstring("'remove' 'Remove a trusted plugin path'"));
|
|
CHECK((fishOutput.find("case 'plugins trust'") == std::string::npos));
|
|
CHECK_THAT(fishOutput, ContainsSubstring("__fish_yams_path_is daemon start"));
|
|
CHECK_THAT(fishOutput,
|
|
ContainsSubstring("-l socket -d 'Socket path for daemon communication' -r"));
|
|
CHECK_THAT(fishOutput, ContainsSubstring("__fish_yams_path_is plugin trust list"));
|
|
CHECK_THAT(fishOutput,
|
|
ContainsSubstring(
|
|
"-l details -d 'Show trust file, defaults, strict mode, and effective roots'"));
|
|
CHECK_THAT(
|
|
fishOutput,
|
|
ContainsSubstring(
|
|
"__fish_yams_path_is daemon start' -l log-level -a 'trace debug info warn error'"));
|
|
CHECK_THAT(
|
|
fishOutput,
|
|
ContainsSubstring(
|
|
"__fish_yams_path_is config search path-tree enable' -l mode -a 'fallback preferred'"));
|
|
}
|
|
|
|
TEST_CASE("CompletionCommand - PowerShell status aliases no longer advertise format",
|
|
"[cli][completion][catch2]") {
|
|
CompletionCliTestHelper helper;
|
|
CaptureStdout capture;
|
|
|
|
const int rc = helper.runCommand({"yams", "completion", "powershell"});
|
|
const std::string output = capture.str();
|
|
|
|
REQUIRE((rc == 0));
|
|
CHECK_THAT(output, ContainsSubstring("'status' = @("));
|
|
CHECK_THAT(output, ContainsSubstring("'stats' = @("));
|
|
CHECK_THAT(output, ContainsSubstring("'config' = @("));
|
|
CHECK_THAT(output, ContainsSubstring("'plugin trust' = @("));
|
|
CHECK((output.find("'plugins trust' = @(") == std::string::npos));
|
|
CHECK_THAT(output, ContainsSubstring("'daemon start' = @("));
|
|
CHECK_THAT(output, ContainsSubstring("'plugin trust list' = @("));
|
|
CHECK_THAT(
|
|
output,
|
|
ContainsSubstring("'daemon start:--log-level' = @('trace','debug','info','warn','error')"));
|
|
CHECK_THAT(output, ContainsSubstring(
|
|
"'config search path-tree enable:--mode' = @('fallback','preferred')"));
|
|
CHECK_THAT(output,
|
|
ContainsSubstring(
|
|
"@{ Name = '--socket'; Description = 'Socket path for daemon communication'"));
|
|
CHECK_THAT(output, ContainsSubstring("@{ Name = '--details'; Description = 'Show trust file, "
|
|
"defaults, strict mode, and effective roots'"));
|
|
CHECK_THAT(output, ContainsSubstring("--no-physical"));
|
|
CHECK_THAT(output, ContainsSubstring("--corpus"));
|
|
CHECK((output.find("'stats' = @(\n @{ Name = '--format'") == std::string::npos));
|
|
}
|
|
|
|
TEST_CASE("CompletionCommand - sourced zsh completion registers compdef",
|
|
"[cli][completion][catch2]") {
|
|
#ifdef _WIN32
|
|
SKIP("zsh completion smoke test requires zsh and Unix process substitution");
|
|
#else
|
|
const fs::path yamsCli = findBuiltYamsCli();
|
|
REQUIRE_FALSE(yamsCli.empty());
|
|
|
|
const fs::path tempDir = yams::test::make_temp_dir("yams_zsh_completion_source_");
|
|
const fs::path dataDir = tempDir / "data";
|
|
fs::create_directories(dataDir);
|
|
const fs::path configPath = tempDir / "config.toml";
|
|
const fs::path out = tempDir / "zsh-sourced-registration.out";
|
|
const fs::path err = tempDir / "zsh-sourced-registration.err";
|
|
{
|
|
std::ofstream cfg(configPath);
|
|
cfg << "[core]\n";
|
|
cfg << "data_dir = \"" << dataDir.string() << "\"\n";
|
|
}
|
|
|
|
if (std::system("command -v zsh >/dev/null 2>&1") != 0) {
|
|
SKIP("zsh completion smoke test requires zsh on PATH");
|
|
}
|
|
|
|
const std::string cmd =
|
|
"env YAMS_CONFIG='" + configPath.string() + "' YAMS_DATA_DIR='" + dataDir.string() +
|
|
"' YAMS_NON_INTERACTIVE=1 YAMS_CLI_DISABLE_DAEMON_AUTOSTART=1 "
|
|
"zsh -fc 'autoload -U compinit; compinit; source <(\"" +
|
|
yamsCli.string() + "\" completion zsh); print -- ${_comps[yams]:-missing}' > '" +
|
|
out.string() + "' 2> '" + err.string() + "'";
|
|
|
|
const int rc = std::system(cmd.c_str());
|
|
REQUIRE(WIFEXITED(rc));
|
|
|
|
std::ifstream outInput(out);
|
|
const std::string stdoutOutput((std::istreambuf_iterator<char>(outInput)),
|
|
std::istreambuf_iterator<char>());
|
|
std::ifstream errInput(err);
|
|
const std::string stderrOutput((std::istreambuf_iterator<char>(errInput)),
|
|
std::istreambuf_iterator<char>());
|
|
const std::string commandStderr = stripCoverageProfilingDiagnostics(stderrOutput);
|
|
INFO("zsh completion command: " << cmd);
|
|
INFO("zsh stdout: " << stdoutOutput);
|
|
INFO("zsh stderr: " << stderrOutput);
|
|
INFO("zsh stderr without coverage profiling diagnostics: " << commandStderr);
|
|
REQUIRE((WEXITSTATUS(rc) == 0));
|
|
|
|
std::string registered;
|
|
std::istringstream registeredInput(stdoutOutput);
|
|
std::getline(registeredInput, registered);
|
|
CHECK((registered == "_yams"));
|
|
|
|
CHECK(commandStderr.empty());
|
|
|
|
std::error_code ec;
|
|
fs::remove_all(tempDir, ec);
|
|
#endif
|
|
}
|