Skip to content

Commit d06a401

Browse files
committed
unify tests include and silence internal check output in vix tests
1 parent e52493f commit d06a401

2 files changed

Lines changed: 163 additions & 27 deletions

File tree

src/commands/NewCommand.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,7 @@ int main()
108108
}
109109
)";
110110

111-
constexpr const char *kBasicTestCpp_App = R"(#include <vix/tests/TestRegistry.hpp>
112-
#include <vix/tests.hpp>
111+
constexpr const char *kBasicTestCpp_App = R"(#include <vix/tests/tests.hpp>
113112
114113
int main()
115114
{
@@ -190,10 +189,7 @@ int main()
190189
std::string s;
191190
s.reserve(1200);
192191

193-
s += "#include <vix/tests/TestRegistry.hpp>\n";
194-
s += "#include <vix/tests/TestRunner.hpp>\n";
195-
s += "#include <vix/tests/TestCase.hpp>\n";
196-
s += "#include <vix/tests/Assert.hpp>\n";
192+
s += "#include <vix/tests/tests.hpp>\n";
197193
s += "#include <" + name + "/" + name + ".hpp>\n\n";
198194

199195
s += "int main()\n";

src/commands/TestsCommand.cpp

Lines changed: 161 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,15 @@
3535

3636
#include <nlohmann/json.hpp>
3737

38+
#include <cstdio>
39+
40+
#ifndef _WIN32
41+
#include <unistd.h>
42+
#include <fcntl.h>
43+
#else
44+
#include <io.h>
45+
#endif
46+
3847
using namespace vix::cli::style;
3948
namespace fs = std::filesystem;
4049

@@ -65,6 +74,124 @@ namespace
6574
return false;
6675
}
6776

77+
struct ScopedSilenceStdStreams
78+
{
79+
bool active{false};
80+
81+
#ifndef _WIN32
82+
int savedStdout{-1};
83+
int savedStderr{-1};
84+
int nullFd{-1};
85+
#else
86+
int savedStdout{-1};
87+
int savedStderr{-1};
88+
int nullFd{-1};
89+
#endif
90+
91+
ScopedSilenceStdStreams()
92+
{
93+
std::fflush(stdout);
94+
std::fflush(stderr);
95+
96+
#ifndef _WIN32
97+
nullFd = ::open("/dev/null", O_WRONLY);
98+
if (nullFd == -1)
99+
return;
100+
101+
savedStdout = ::dup(STDOUT_FILENO);
102+
savedStderr = ::dup(STDERR_FILENO);
103+
104+
if (savedStdout == -1 || savedStderr == -1)
105+
{
106+
if (savedStdout != -1)
107+
::close(savedStdout);
108+
if (savedStderr != -1)
109+
::close(savedStderr);
110+
::close(nullFd);
111+
savedStdout = -1;
112+
savedStderr = -1;
113+
nullFd = -1;
114+
return;
115+
}
116+
117+
if (::dup2(nullFd, STDOUT_FILENO) == -1 ||
118+
::dup2(nullFd, STDERR_FILENO) == -1)
119+
{
120+
::dup2(savedStdout, STDOUT_FILENO);
121+
::dup2(savedStderr, STDERR_FILENO);
122+
::close(savedStdout);
123+
::close(savedStderr);
124+
::close(nullFd);
125+
savedStdout = -1;
126+
savedStderr = -1;
127+
nullFd = -1;
128+
return;
129+
}
130+
131+
active = true;
132+
#else
133+
nullFd = _open("NUL", _O_WRONLY);
134+
if (nullFd == -1)
135+
return;
136+
137+
savedStdout = _dup(_fileno(stdout));
138+
savedStderr = _dup(_fileno(stderr));
139+
140+
if (savedStdout == -1 || savedStderr == -1)
141+
{
142+
if (savedStdout != -1)
143+
_close(savedStdout);
144+
if (savedStderr != -1)
145+
_close(savedStderr);
146+
_close(nullFd);
147+
savedStdout = -1;
148+
savedStderr = -1;
149+
nullFd = -1;
150+
return;
151+
}
152+
153+
if (_dup2(nullFd, _fileno(stdout)) == -1 ||
154+
_dup2(nullFd, _fileno(stderr)) == -1)
155+
{
156+
_dup2(savedStdout, _fileno(stdout));
157+
_dup2(savedStderr, _fileno(stderr));
158+
_close(savedStdout);
159+
_close(savedStderr);
160+
_close(nullFd);
161+
savedStdout = -1;
162+
savedStderr = -1;
163+
nullFd = -1;
164+
return;
165+
}
166+
167+
active = true;
168+
#endif
169+
}
170+
171+
~ScopedSilenceStdStreams()
172+
{
173+
if (!active)
174+
return;
175+
176+
std::fflush(stdout);
177+
std::fflush(stderr);
178+
179+
#ifndef _WIN32
180+
::dup2(savedStdout, STDOUT_FILENO);
181+
::dup2(savedStderr, STDERR_FILENO);
182+
::close(savedStdout);
183+
::close(savedStderr);
184+
::close(nullFd);
185+
#else
186+
_dup2(savedStdout, _fileno(stdout));
187+
_dup2(savedStderr, _fileno(stderr));
188+
_close(savedStdout);
189+
_close(savedStderr);
190+
_close(nullFd);
191+
#endif
192+
}
193+
};
194+
68195
static bool is_watched_file(const fs::path &p)
69196
{
70197
const auto ext = p.extension().string();
@@ -363,12 +490,18 @@ namespace
363490
return vix::cli::process::normalize_exit_code(raw);
364491
}
365492

493+
static std::string project_name_from_dir(const fs::path &projectDir)
494+
{
495+
std::string name = projectDir.filename().string();
496+
if (name.empty())
497+
name = "app";
498+
return name;
499+
}
500+
366501
static int ensure_project_configured_and_built(
367502
const vix::commands::TestsCommand::detail::Options &opt,
368503
const std::string &presetName)
369504
{
370-
info("Tests are not ready. Auto-configure/auto-build via `vix check`.");
371-
372505
std::vector<std::string> forwarded = opt.forwarded;
373506

374507
if (!has_flag(forwarded, "--tests"))
@@ -381,6 +514,30 @@ namespace
381514
forwarded.push_back(presetName);
382515
}
383516

517+
const std::string projectName = project_name_from_dir(opt.projectDir);
518+
const std::string testFlag = "-D" + projectName + "_BUILD_TESTS=ON";
519+
520+
bool hasDashDash = false;
521+
bool hasTestFlag = false;
522+
523+
for (const auto &arg : forwarded)
524+
{
525+
if (arg == "--")
526+
hasDashDash = true;
527+
528+
if (arg == testFlag)
529+
hasTestFlag = true;
530+
}
531+
532+
if (!hasTestFlag)
533+
{
534+
if (!hasDashDash)
535+
forwarded.push_back("--");
536+
537+
forwarded.push_back(testFlag);
538+
}
539+
540+
ScopedSilenceStdStreams silence;
384541
return vix::commands::CheckCommand::run(forwarded);
385542
}
386543

@@ -567,17 +724,7 @@ namespace
567724
const auto runner = find_native_test_runner(refreshedBuildDir);
568725

569726
if (!runner)
570-
{
571-
error("Native test runner not found.");
572-
hint("Expected a built test executable from the project or umbrella.");
573-
step(std::string("Build dir: ") + refreshedBuildDir.string());
574727
return 2;
575-
}
576-
577-
info("Running tests (native runner).");
578-
hint(std::string("Preset: ") + presetName);
579-
hint(std::string("Build dir: ") + refreshedBuildDir.string());
580-
hint(std::string("Runner: ") + runner->string());
581728

582729
std::vector<std::string> argv;
583730
argv.push_back(runner->string());
@@ -609,16 +756,11 @@ namespace
609756

610757
if (!ctest_file_exists(refreshedBuildDir))
611758
{
612-
error("CTest metadata is not available.");
613-
hint("Tests may be disabled in the project or no CTest entries were generated.");
614-
step(std::string("Expected file: ") + (refreshedBuildDir / "CTestTestfile.cmake").string());
759+
error("No tests available.");
760+
hint("Tests are disabled for this project in the current CMake configuration.");
615761
return 1;
616762
}
617763

618-
info("Running tests (CTest fallback).");
619-
hint(std::string("Preset: ") + presetName);
620-
hint(std::string("Build dir: ") + refreshedBuildDir.string());
621-
622764
std::vector<std::string> argv;
623765
argv.push_back("ctest");
624766

@@ -640,10 +782,8 @@ namespace
640782
if (nativeCode != 2)
641783
return nativeCode;
642784

643-
info("Falling back to CTest.");
644785
return run_ctest(opt);
645786
}
646-
647787
} // namespace
648788

649789
namespace vix::commands::TestsCommand

0 commit comments

Comments
 (0)