mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-05 09:33:25 -08:00
[Fonts] Add AppFont roles and FontConfig fonts.toml round-trip
This commit is contained in:
parent
c72192fd81
commit
d34bb81884
4 changed files with 399 additions and 2 deletions
195
tests/font_config_test.cpp
Normal file
195
tests/font_config_test.cpp
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
#include "interface/theme_config.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QFont>
|
||||
#include <QIODevice>
|
||||
#include <QString>
|
||||
#include <QStringLiteral>
|
||||
#include <QTemporaryDir>
|
||||
#include <QTextStream>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
// Writes content to a file inside tmp, creating parents as needed.
|
||||
QString writeTempFile(QTemporaryDir &tmp, const QString &relativePath, const QString &content)
|
||||
{
|
||||
const QString filePath = QDir(tmp.path()).absoluteFilePath(relativePath);
|
||||
EXPECT_TRUE(QDir().mkpath(QFileInfo(filePath).absolutePath()));
|
||||
QFile file(filePath);
|
||||
EXPECT_TRUE(file.open(QIODevice::WriteOnly | QIODevice::Text));
|
||||
QTextStream out(&file);
|
||||
out << content;
|
||||
file.close();
|
||||
return filePath;
|
||||
}
|
||||
|
||||
QFont makeFont(const QString &family, int pointSize)
|
||||
{
|
||||
QFont font(family);
|
||||
font.setPointSize(pointSize);
|
||||
return font;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST(FontConfigTest, FileNameIsFontsToml)
|
||||
{
|
||||
EXPECT_EQ(FontConfig::fileName(), QStringLiteral("fonts.toml"));
|
||||
}
|
||||
|
||||
TEST(FontConfigTest, EmptyByDefault)
|
||||
{
|
||||
FontConfig cfg;
|
||||
EXPECT_FALSE(cfg.hasFonts());
|
||||
EXPECT_TRUE(cfg.toToml().isEmpty());
|
||||
EXPECT_EQ(cfg, FontConfig());
|
||||
EXPECT_EQ(cfg, FontConfig::fromFile("/nonexistent/path/fonts.toml"));
|
||||
EXPECT_EQ(cfg, FontConfig::fromThemeDir(QString()));
|
||||
}
|
||||
|
||||
TEST(FontConfigTest, RoundTripPreservesFamilyAndSize)
|
||||
{
|
||||
QTemporaryDir tmp;
|
||||
ASSERT_TRUE(tmp.isValid());
|
||||
|
||||
FontConfig cfg;
|
||||
cfg.fonts[AppFont::InterfaceDefault] = makeFont("Inter", 10);
|
||||
cfg.fonts[AppFont::ChatLog] = makeFont("JetBrains Mono", 9);
|
||||
cfg.fonts[AppFont::CardText] = makeFont("Noto Serif", 11);
|
||||
cfg.fonts[AppFont::DeckList] = makeFont("Roboto", 12);
|
||||
ASSERT_TRUE(cfg.hasFonts());
|
||||
|
||||
const QString filePath = writeTempFile(tmp, "fonts.toml", cfg.toToml());
|
||||
const FontConfig loaded = FontConfig::fromFile(filePath);
|
||||
|
||||
EXPECT_EQ(loaded, cfg);
|
||||
EXPECT_EQ(loaded.fonts[AppFont::InterfaceDefault].family(), QStringLiteral("Inter"));
|
||||
EXPECT_EQ(loaded.fonts[AppFont::InterfaceDefault].pointSize(), 10);
|
||||
EXPECT_EQ(loaded.fonts[AppFont::ChatLog].family(), QStringLiteral("JetBrains Mono"));
|
||||
EXPECT_EQ(loaded.fonts[AppFont::ChatLog].pointSize(), 9);
|
||||
EXPECT_EQ(loaded.fonts[AppFont::CardText].family(), QStringLiteral("Noto Serif"));
|
||||
EXPECT_EQ(loaded.fonts[AppFont::CardText].pointSize(), 11);
|
||||
EXPECT_EQ(loaded.fonts[AppFont::DeckList].family(), QStringLiteral("Roboto"));
|
||||
EXPECT_EQ(loaded.fonts[AppFont::DeckList].pointSize(), 12);
|
||||
}
|
||||
|
||||
TEST(FontConfigTest, RoundTripStripsWeightAndItalic)
|
||||
{
|
||||
QTemporaryDir tmp;
|
||||
ASSERT_TRUE(tmp.isValid());
|
||||
|
||||
QFont styled("Inter");
|
||||
styled.setPointSize(10);
|
||||
styled.setBold(true);
|
||||
styled.setItalic(true);
|
||||
|
||||
FontConfig cfg;
|
||||
cfg.fonts[AppFont::ChatLog] = styled;
|
||||
|
||||
const QString filePath = writeTempFile(tmp, "fonts.toml", cfg.toToml());
|
||||
const FontConfig loaded = FontConfig::fromFile(filePath);
|
||||
|
||||
ASSERT_TRUE(loaded.fonts.contains(AppFont::ChatLog));
|
||||
EXPECT_EQ(loaded.fonts[AppFont::ChatLog].family(), QStringLiteral("Inter"));
|
||||
EXPECT_EQ(loaded.fonts[AppFont::ChatLog].pointSize(), 10);
|
||||
EXPECT_FALSE(loaded.fonts[AppFont::ChatLog].bold());
|
||||
EXPECT_FALSE(loaded.fonts[AppFont::ChatLog].italic());
|
||||
EXPECT_EQ(loaded.fonts[AppFont::ChatLog], makeFont("Inter", 10));
|
||||
}
|
||||
|
||||
TEST(FontConfigTest, ToTomlFormat)
|
||||
{
|
||||
FontConfig cfg;
|
||||
cfg.fonts[AppFont::InterfaceDefault] = makeFont("Inter", 10);
|
||||
|
||||
const QString toml = cfg.toToml();
|
||||
EXPECT_TRUE(toml.contains(QStringLiteral("[Fonts]")));
|
||||
EXPECT_TRUE(toml.contains(QStringLiteral("InterfaceDefault")));
|
||||
EXPECT_TRUE(toml.contains(QStringLiteral("\"Inter, 10\"")));
|
||||
}
|
||||
|
||||
TEST(FontConfigTest, MalformedLinesAreSkipped)
|
||||
{
|
||||
QTemporaryDir tmp;
|
||||
ASSERT_TRUE(tmp.isValid());
|
||||
|
||||
const QString filePath = writeTempFile(tmp, "fonts.toml",
|
||||
"# a comment\n"
|
||||
"; another comment\n"
|
||||
"\n"
|
||||
"StrayBeforeSection = \"Inter, 10\"\n"
|
||||
"\n"
|
||||
"[Other]\n"
|
||||
"ChatLog = \"ShouldBeIgnored, 10\"\n"
|
||||
"\n"
|
||||
"[Fonts]\n"
|
||||
"InterfaceDefault = \"Inter, 10\"\n"
|
||||
"ChatLog = \"JetBrains Mono\", 9 # inline comment\n"
|
||||
"CardText = Noto Serif, 11\n"
|
||||
"AppFont::DeckList = \"Roboto, 12\"\n"
|
||||
"UnknownRole = \"Inter, 10\"\n"
|
||||
"QPalette::Window = \"Inter, 10\"\n"
|
||||
"NoComma = \"Inter\"\n"
|
||||
"EmptyFamily = \", 10\"\n"
|
||||
"ZeroSize = \"Inter, 0\"\n"
|
||||
"NegativeSize = \"Inter, -3\"\n"
|
||||
"NotANumber = \"Inter, big\"\n"
|
||||
"NotAnEntry\n");
|
||||
|
||||
const FontConfig loaded = FontConfig::fromFile(filePath);
|
||||
|
||||
ASSERT_TRUE(loaded.hasFonts());
|
||||
EXPECT_EQ(loaded.fonts.size(), 4);
|
||||
EXPECT_EQ(loaded.fonts[AppFont::InterfaceDefault], makeFont("Inter", 10));
|
||||
EXPECT_EQ(loaded.fonts[AppFont::ChatLog], makeFont("JetBrains Mono", 9));
|
||||
EXPECT_EQ(loaded.fonts[AppFont::CardText], makeFont("Noto Serif", 11));
|
||||
EXPECT_EQ(loaded.fonts[AppFont::DeckList], makeFont("Roboto", 12));
|
||||
}
|
||||
|
||||
TEST(FontConfigTest, FromThemeDirReadsFontsToml)
|
||||
{
|
||||
QTemporaryDir tmp;
|
||||
ASSERT_TRUE(tmp.isValid());
|
||||
|
||||
const QString themeDir = QDir(tmp.path()).absoluteFilePath("MyTheme");
|
||||
ASSERT_TRUE(QDir().mkpath(themeDir));
|
||||
|
||||
FontConfig cfg;
|
||||
cfg.fonts[AppFont::CardText] = makeFont("Noto Serif", 11);
|
||||
writeTempFile(tmp, "MyTheme/fonts.toml", cfg.toToml());
|
||||
|
||||
const FontConfig loaded = FontConfig::fromThemeDir(themeDir);
|
||||
EXPECT_EQ(loaded, cfg);
|
||||
|
||||
// A theme directory without fonts.toml loads as empty.
|
||||
const QString bareDir = QDir(tmp.path()).absoluteFilePath("BareTheme");
|
||||
ASSERT_TRUE(QDir().mkpath(bareDir));
|
||||
EXPECT_FALSE(FontConfig::fromThemeDir(bareDir).hasFonts());
|
||||
}
|
||||
|
||||
TEST(FontConfigTest, InequalityComparesRoles)
|
||||
{
|
||||
FontConfig left;
|
||||
left.fonts[AppFont::InterfaceDefault] = makeFont("Inter", 10);
|
||||
|
||||
FontConfig right = left;
|
||||
EXPECT_EQ(left, right);
|
||||
EXPECT_FALSE(left != right);
|
||||
|
||||
right.fonts[AppFont::InterfaceDefault] = makeFont("Inter", 11);
|
||||
EXPECT_NE(left, right);
|
||||
|
||||
right = left;
|
||||
right.fonts[AppFont::ChatLog] = makeFont("Inter", 10);
|
||||
EXPECT_NE(left, right);
|
||||
}
|
||||
|
||||
// Every test brings its own main(): GTest is not guaranteed to be found on the build machines, and
|
||||
// the fallback then links the bare gtest library without gtest_main.
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue