diff options
| author | Leitwolf11 | 2026-11-01 22:16:14 +0300 |
|---|---|---|
| committer | Leitwolf11 | 2026-11-01 22:16:14 +0300 |
| commit | da3c9d0880dbd4a74e0e43f092d10f5ae42c5043 (patch) | |
| tree | 4676a526585dbb0e2f6d8c9c18978ed01092c2e2 /tools/Tools.tests.cpp | |
| parent | 241b5567d09d59e82bff18287c32ada480deb8c0 (diff) | |
| download | catch3-da3c9d0880dbd4a74e0e43f092d10f5ae42c5043.tar.gz | |
Move the tools from Python to C++17 and Bazel
The scripts in use become programs run with `bazelisk run //tools:<tool>`,
and arguments follow `--`:
amalgamate the single-file distribution; --check only compares it
check licenses, convenience headers, header guards, file names,
versions and whether the distribution is up to date
third-party compares third_party/ with its archives, or writes it
version prints the version, or moves every place that states it
release-notes prints a section of the release notes
repo-info reports the checkout and the tools on PATH; --json writes
it through yyjson, with the fields of Tala's repo-info
amalgamate writes what the Python script wrote, byte for byte, except for
the time of generation. That line is gone so that the output is
deterministic and --check can compare it.
MODULE.bazel now pins the archives of third_party/ by version and sha256,
so Bazel fetches and checks them instead of a tool of ours, and Renovate
reads the versions there.
Scripts nobody used are gone: fixWhitespace, updateDocumentSnippets,
buildAndTest, and updateDocumentToC, which rewrote unrelated documents.
CheckConvenienceHeaders leaves CTest, since //tools:check runs it in CI.
The Python of tests/TestScripts stays: those are tests, not tools.
Diffstat (limited to 'tools/Tools.tests.cpp')
| -rw-r--r-- | tools/Tools.tests.cpp | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/tools/Tools.tests.cpp b/tools/Tools.tests.cpp new file mode 100644 index 00000000..51dca951 --- /dev/null +++ b/tools/Tools.tests.cpp @@ -0,0 +1,116 @@ +// Copyright (c) 2026 Progmasoft. +// SPDX-License-Identifier: MPL-2.0 WITH AdditionRef-Progmasoft-Exception-2.0 + +#include <Progmasoft/Catch3/TestMacros.hpp> +#include <string> + +#include "tools/Amalgamation.hpp" +#include "tools/Repository.hpp" +#include "tools/RepositoryReport.hpp" +#include "tools/Versions.hpp" + +using namespace Progmasoft::Catch3::Tools; + +TEST_CASE("Versions have three or four numbers", "[tools]") +{ + CHECK(ParseVersion("0.3.0") == Version{ 0, 3, 0, 0 }); + CHECK(ParseVersion("0.3.0.2") == Version{ 0, 3, 0, 2 }); + for (const char *wrong : + { "0.3", "0.3.0.2.1", "01.3.0", "0.3.0.", "a.3.0", "", "0.3.0-rc" }) + { + INFO(wrong); + CHECK_FALSE(ParseVersion(wrong)); + } +} + +TEST_CASE("The next version counts releases", "[tools]") +{ + const auto next = [](const char *version) { + return FormatVersion(NextVersion(*ParseVersion(version))); + }; + CHECK(next("0.3.0") == "0.3.0.1"); + CHECK(next("0.4.0.8") == "0.4.0.9"); + CHECK(next("0.4.0.9") == "0.4.1.0"); + CHECK(next("0.4.9.9") == "0.5.0.0"); + CHECK(next("0.19.9.9") == "1.0.0.0"); +} + +TEST_CASE("A version site is read and written in place", "[tools]") +{ + const VersionSite site{ "file", "version: '", "'" }; + const std::string text = "name\n version: '1.2.3',\n version: '9'\n"; + CHECK(ReadVersionSite(text, site) == "1.2.3"); + CHECK(WriteVersionSite(text, site, "1.2.3.4") + == "name\n version: '1.2.3.4',\n version: '9'\n"); + CHECK_FALSE(ReadVersionSite("name", site)); + CHECK_FALSE(WriteVersionSite("name", site, "1")); +} + +TEST_CASE("Release notes are found by their heading", "[tools]") +{ + const std::string notes = "# Release notes\n\n## 0.2\n\nNew.\n\n" + "### Part\n\n* One.\n\n\n## 0.1\n\nOld.\n"; + CHECK(ReleaseNotesOf(notes, "0.2") == "New.\n\n### Part\n\n* One.\n"); + CHECK(ReleaseNotesOf(notes, "0.1") == "Old.\n"); + CHECK_FALSE(ReleaseNotesOf(notes, "0.3")); +} + +TEST_CASE("Includes are read as they are written", "[tools]") +{ + const auto angled = ParseInclude(" #include <a/b.hpp> // why\n"); + REQUIRE(angled); + CHECK(angled->Name == "a/b.hpp"); + CHECK(angled->Angled); + const auto quoted = ParseInclude("#include \"b.hpp\"\n"); + REQUIRE(quoted); + CHECK_FALSE(quoted->Angled); + CHECK_FALSE(ParseInclude("# include <a.hpp>\n")); + CHECK_FALSE(ParseInclude("// #include <a.hpp>\n")); + CHECK_FALSE(ParseInclude("#include MACRO\n")); +} + +TEST_CASE("The engine version comes from its declaration", "[tools]") +{ + CHECK(ParseEngineVersion(" static Version version( 3, 16, 1, \"\", 0 );") + == "3.16.1"); + CHECK(ParseEngineVersion("static Version version( 3, 17, 0, \"rc\", 2 );") + == "3.17.0-rc.2"); + CHECK_FALSE(ParseEngineVersion("nothing here")); +} + +TEST_CASE("A report becomes JSON", "[tools]") +{ + RepositoryReport report; + report.Root = "C:\\repos\\catch3"; + report.Os = "windows"; + report.Branch = "devel"; + report.Dirty = true; + report.Tools.push_back({ "git", "/usr/bin/git", true }); + report.Tools.push_back({ "ninja", "", false }); + CHECK(ReportToJson(report) == R"({ + "root": "C:\\repos\\catch3", + "os": "windows", + "branch": "devel", + "dirty": true, + "tools": [ + { + "name": "git", + "path": "/usr/bin/git", + "available": true + }, + { + "name": "ninja", + "available": false + } + ] +} +)"); +} + +TEST_CASE("Text helpers keep line ends", "[tools]") +{ + CHECK(SplitLines("a\nb") == std::vector<std::string>{ "a\n", "b" }); + CHECK(SplitLines("").empty()); + CHECK(Trimmed(" a b\r\n") == "a b"); + CHECK(Trimmed(" \n").empty()); +} |