Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/tools/Tools.tests.cpp
diff options
context:
space:
mode:
authorLeitwolf2026-11-02 00:51:11 +0300
committerGitHub2026-11-02 00:51:11 +0300
commit268698be92962247a21a86dda4de2d4267adcf8f (patch)
tree510f7ece1750b2da6d9b4666b7c58908c8d193bb /tools/Tools.tests.cpp
parent13324a043042110eba456424fa39c1334857ceaa (diff)
parent3ed0fd930371823b6d44ae64d00dbd79e421a552 (diff)
downloadcatch3-268698be92962247a21a86dda4de2d4267adcf8f.tar.gz
Merge pull request #36 from Progmasoft/feature/cpp-tools
Move the tools from Python to C++17 and Bazel
Diffstat (limited to 'tools/Tools.tests.cpp')
-rw-r--r--tools/Tools.tests.cpp137
1 files changed, 137 insertions, 0 deletions
diff --git a/tools/Tools.tests.cpp b/tools/Tools.tests.cpp
new file mode 100644
index 00000000..90e9b129
--- /dev/null
+++ b/tools/Tools.tests.cpp
@@ -0,0 +1,137 @@
+// Copyright (c) 2026 Progmasoft.
+// SPDX-License-Identifier: MPL-2.0 WITH AdditionRef-Progmasoft-Exception-2.0
+
+#include <Progmasoft/Catch3/Matchers/String.hpp>
+#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;
+using Catch::Matchers::ContainsSubstring;
+
+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("A release with D = 0 may be headed by three numbers", "[tools]")
+{
+ const std::string notes = "# Notes\n\n## 0.4.0\n\nThree.\n";
+ CHECK(ReleaseNotesOf(notes, "0.4.0") == "Three.\n");
+ CHECK(ReleaseNotesOf(notes, "0.4.0.0") == "Three.\n");
+ CHECK_FALSE(ReleaseNotesOf(notes, "0.4.0.1"));
+}
+
+TEST_CASE("Git that could not say is not a clean checkout", "[tools]")
+{
+ RepositoryReport report;
+ report.GitError = "unreadable";
+ CHECK_THAT(ReportToJson(report), ContainsSubstring("\"dirty\": null"));
+ CHECK_THAT(FormatReport(report),
+ ContainsSubstring("Tracked changes: unknown"));
+ report.Dirty = false;
+ CHECK_THAT(ReportToJson(report), ContainsSubstring("\"dirty\": false"));
+}
+
+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());
+}