Give Effector a version and a changelog, shown from the menu
The version is the project() line of CMakeLists.txt and nowhere else: CMake writes it, with the text of CHANGELOG.md, into a generated core/version.hpp, so the number and the release notes the binary shows are the ones it was built from. effector --version (-V) prints it, and the header-bar menu gains a section with Changelog, a window laying the Markdown out as headings and bullets, and About Effector. The core tests hold the newest changelog entry to the current version, so a bump cannot go in without its notes. Releases are tagged vX.Y.Z; this is 0.5.0, and the changelog reconstructs 0.1.0-0.4.0 from the history. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
#include "cli/options.hpp"
|
||||
#include "core/project.hpp"
|
||||
#include "core/registry.hpp"
|
||||
#include "core/version.hpp"
|
||||
#include "gui/window.hpp"
|
||||
|
||||
namespace {
|
||||
@@ -375,6 +376,45 @@ std::vector<std::string> recentEntries(Gtk::Window& window) {
|
||||
return labels;
|
||||
}
|
||||
|
||||
// The version and the changelog, each a menu entry away.
|
||||
void testHelpWindows(Gtk::Window& window) {
|
||||
std::cout << "changelog and about\n";
|
||||
auto toplevel = [](const std::string& title) -> Gtk::Window* {
|
||||
for (auto* w : Gtk::Window::list_toplevels()) {
|
||||
if (w->get_title() == title && w->get_visible()) return w;
|
||||
}
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
window.activate_action("win.show-changelog");
|
||||
pump(200);
|
||||
auto* changelog = toplevel("Changelog");
|
||||
check(changelog != nullptr, "Changelog opens a window");
|
||||
auto* text = changelog != nullptr ? named<Gtk::TextView>(*changelog, "changelog") : nullptr;
|
||||
const std::string shown = text != nullptr ? std::string(text->get_buffer()->get_text()) : "";
|
||||
check(shown.find(std::string(effector::kVersion) + " — ") != std::string::npos,
|
||||
"listing this version as a release");
|
||||
check(shown.find("[") == std::string::npos && shown.find("`") == std::string::npos &&
|
||||
shown.find("### ") == std::string::npos,
|
||||
"with the Markdown laid out rather than shown");
|
||||
if (changelog != nullptr) changelog->close();
|
||||
pump(50);
|
||||
check(toplevel("Changelog") == nullptr, "and closes");
|
||||
|
||||
window.activate_action("win.about");
|
||||
pump(200);
|
||||
Gtk::AboutDialog* about = nullptr;
|
||||
for (auto* w : Gtk::Window::list_toplevels()) {
|
||||
if (auto* dialog = dynamic_cast<Gtk::AboutDialog*>(w); dialog != nullptr && dialog->get_visible()) {
|
||||
about = dialog;
|
||||
}
|
||||
}
|
||||
check(about != nullptr && about->get_version() == std::string(effector::kVersion),
|
||||
"About Effector shows the version");
|
||||
if (about != nullptr) about->close();
|
||||
pump(50);
|
||||
}
|
||||
|
||||
void testRecentProjects(Gtk::Window& window, const std::filesystem::path& dir) {
|
||||
std::cout << "recent projects\n";
|
||||
check(recentEntries(window) == std::vector<std::string>{"No Recent Projects"},
|
||||
@@ -425,6 +465,7 @@ int main(int argc, char** argv) {
|
||||
window->present();
|
||||
pump(300);
|
||||
runTests(*window);
|
||||
testHelpWindows(*window);
|
||||
testRecentProjects(*window, dataDir / "projects");
|
||||
app->remove_window(*window);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user