153 lines
5.2 KiB
C++
153 lines
5.2 KiB
C++
#include "TestLayouts.h"
|
||
|
||
#include <QTest>
|
||
#include <xkbcommon/xkbcommon-keysyms.h>
|
||
|
||
using namespace Qt::StringLiterals;
|
||
|
||
namespace {
|
||
|
||
QString rowLetters(const Layout &layout, int row)
|
||
{
|
||
QString letters;
|
||
for (const KeyDef &key : layout.layers.first().rows[row]) {
|
||
if (key.type == KeyType::Character && key.label.front().isLetter())
|
||
letters += key.label;
|
||
}
|
||
return letters;
|
||
}
|
||
|
||
const KeyDef &letterKey(const Layout &layout, const QString &label)
|
||
{
|
||
for (const Row &row : layout.layers.first().rows) {
|
||
for (const KeyDef &key : row) {
|
||
if (key.label == label)
|
||
return key;
|
||
}
|
||
}
|
||
qFatal("no key %s", qPrintable(label));
|
||
}
|
||
|
||
} // namespace
|
||
|
||
class TestLayoutBuilder : public QObject
|
||
{
|
||
Q_OBJECT
|
||
|
||
private Q_SLOTS:
|
||
void readsLetterRowsFromKeymap()
|
||
{
|
||
const Layout us = TestLayouts::build("us");
|
||
QCOMPARE(rowLetters(us, 0), u"qwertyuiop");
|
||
QCOMPARE(rowLetters(us, 1), u"asdfghjkl");
|
||
QCOMPARE(rowLetters(us, 2), u"zxcvbnm");
|
||
|
||
const Layout sk = TestLayouts::build("sk");
|
||
QCOMPARE(sk.name, u"Slovak");
|
||
QCOMPARE(rowLetters(sk, 0), u"qwertzuiopúä");
|
||
QCOMPARE(rowLetters(sk, 1), u"asdfghjklô");
|
||
QCOMPARE(rowLetters(sk, 2), u"yxcvbnm");
|
||
|
||
const Layout se = TestLayouts::build("se");
|
||
QCOMPARE(rowLetters(se, 0), u"qwertyuiopå");
|
||
QCOMPARE(rowLetters(se, 1), u"asdfghjklöä");
|
||
}
|
||
|
||
void shiftedFormComesFromKeymap()
|
||
{
|
||
QCOMPARE(letterKey(TestLayouts::build("sk"), u"ô"_s).shifted, u"Ô");
|
||
}
|
||
|
||
void flicksFollowColumns()
|
||
{
|
||
const Layout sk = TestLayouts::build("sk");
|
||
QCOMPARE(letterKey(sk, u"q"_s).flick, u"1");
|
||
QCOMPARE(letterKey(sk, u"p"_s).flick, u"0");
|
||
QVERIFY(letterKey(sk, u"ú"_s).flick.isEmpty()); // more letters than flicks
|
||
}
|
||
|
||
void numberRowLettersBecomeAlternates()
|
||
{
|
||
const Layout sk = TestLayouts::build("sk");
|
||
// The keymap's own letters come first: they're what this language types.
|
||
QCOMPARE(letterKey(sk, u"s"_s).alternates.first(), u"š");
|
||
QCOMPARE(letterKey(sk, u"l"_s).alternates.first(), u"ľ");
|
||
QCOMPARE(letterKey(sk, u"n"_s).alternates.first(), u"ň"); // BKSL on sk
|
||
QCOMPARE(letterKey(sk, u"e"_s).alternates.first(), u"é");
|
||
QCOMPARE(letterKey(sk, u"y"_s).alternates.first(), u"ý");
|
||
}
|
||
|
||
void lettersWithoutDecompositionFindTheirBase()
|
||
{
|
||
QCOMPARE(letterKey(TestLayouts::build("de"), u"s"_s).alternates.first(), u"ß");
|
||
}
|
||
|
||
void alternatesSkipLettersThatHaveKeys()
|
||
{
|
||
const Layout se = TestLayouts::build("se");
|
||
const QStringList a = letterKey(se, u"a"_s).alternates;
|
||
QVERIFY(!a.contains(u"ä"_s));
|
||
QVERIFY(!a.contains(u"å"_s));
|
||
QVERIFY(a.contains(u"á"_s));
|
||
}
|
||
|
||
void fullModeHasEveryTypingKey()
|
||
{
|
||
const Layout us = TestLayouts::build("us", KeyboardMode::Full);
|
||
const auto labels = [&](int row) {
|
||
QString text;
|
||
for (const KeyDef &key : us.layers.first().rows[row]) {
|
||
if (key.type == KeyType::Character)
|
||
text += key.label;
|
||
}
|
||
return text;
|
||
};
|
||
QCOMPARE(labels(0), u"`1234567890-=");
|
||
QCOMPARE(labels(1), u"qwertyuiop[]\\");
|
||
QCOMPARE(labels(2), u"asdfghjkl;'");
|
||
QCOMPARE(labels(3), u"zxcvbnm,./"); // LSGT (< >) repeats , . shifted: left out
|
||
QCOMPARE(letterKey(us, u"1"_s).flick, u"!");
|
||
QCOMPARE(letterKey(us, u"1"_s).shifted, u"!");
|
||
}
|
||
|
||
void fullModeRowsStagger()
|
||
{
|
||
// The key ahead of A, and of the first key on the Z row: like a hardware keyboard,
|
||
// with the ISO key (sk: |) taking its room from left shift.
|
||
const auto offsets = [](const Layout &layout) {
|
||
const QList<Row> &rows = layout.layers.first().rows;
|
||
return std::pair{rows[2].first().width, rows[3].first().width};
|
||
};
|
||
QCOMPARE(offsets(TestLayouts::build("us", KeyboardMode::Full)), std::pair(1.75, 2.25));
|
||
const Layout sk = TestLayouts::build("sk", KeyboardMode::Full);
|
||
QCOMPARE(offsets(sk), std::pair(1.75, 1.25));
|
||
QCOMPARE(sk.layers.first().rows[3].at(1).label, u"\\"_s);
|
||
}
|
||
|
||
void fullModeKeepsDeadKeysAndKeymapShift()
|
||
{
|
||
const Layout sk = TestLayouts::build("sk", KeyboardMode::Full);
|
||
const KeyDef acute = letterKey(sk, u"´"_s);
|
||
QCOMPARE(acute.dead, quint32(XKB_KEY_dead_acute));
|
||
QCOMPARE(acute.deadShifted, quint32(XKB_KEY_dead_caron));
|
||
QCOMPARE(letterKey(sk, u"ô"_s).shifted, u"\""); // as the physical key
|
||
QCOMPARE(letterKey(sk, u"ľ"_s).shifted, u"2");
|
||
// Number-row letters are still long-press choices on their base letter.
|
||
QCOMPARE(letterKey(sk, u"t"_s).alternates.first(), u"ť");
|
||
QCOMPARE(letterKey(sk, u"l"_s).alternates.first(), u"ľ");
|
||
}
|
||
|
||
void noPlaceholdersRemain()
|
||
{
|
||
for (const Layer &layer : TestLayouts::build("us").layers) {
|
||
for (const Row &row : layer.rows) {
|
||
for (const KeyDef &key : row)
|
||
QVERIFY(key.type != KeyType::Letters);
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
QTEST_GUILESS_MAIN(TestLayoutBuilder)
|
||
#include "tst_layoutbuilder.moc"
|