Files
sloposk/tests/tst_shiftstate.cpp
ericek111andClaude Opus 5.5 d44aab7772 Keep the user's shift; trust the text guess less
- A tapped shift (on or off) survives the field re-reporting its context:
  it lasts until a character is typed, the hint changes or a field is focused
- An input-method reset forgets the guessed text and pending dead key, so
  double-space can't delete a character the keyboard never saw
- Fields that state typing preferences only get capitals if they ask
- Trackpad moves in fields without surrounding text make the guess unknown;
  Backspace removes a whole grapheme cluster from it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 10:13:27 +02:00

158 lines
3.8 KiB
C++

#include "input/ShiftState.h"
#include <QTest>
using Mode = ShiftState::Mode;
class TestShiftState : public QObject
{
Q_OBJECT
private Q_SLOTS:
void tapShiftsOneCharacter()
{
ShiftState shift;
shift.press(0);
shift.release();
QCOMPARE(shift.mode(), Mode::Once);
shift.characterTyped();
QCOMPARE(shift.mode(), Mode::Off);
}
void doubleTapLocks()
{
ShiftState shift;
shift.press(0);
shift.release();
shift.press(200);
shift.release();
QCOMPARE(shift.mode(), Mode::Locked);
shift.characterTyped();
shift.characterTyped();
QCOMPARE(shift.mode(), Mode::Locked);
}
void doubleTapLocksAfterAutomaticShift()
{
ShiftState shift;
shift.setAutomatic(true);
shift.press(0); // turns auto-shift off...
shift.release();
shift.press(200); // ...and the second tap locks
shift.release();
QCOMPARE(shift.mode(), Mode::Locked);
}
void tapAfterUnlockIsNotDoubleTap()
{
ShiftState shift;
shift.press(0);
shift.press(100); // locked
shift.press(1000); // unlocks
shift.press(1100);
QCOMPARE(shift.mode(), Mode::Once);
}
void typingBetweenTapsIsNotDoubleTap()
{
ShiftState shift;
shift.press(0);
shift.release();
shift.characterTyped();
shift.press(200);
QCOMPARE(shift.mode(), Mode::Once);
}
void tapUnlocks()
{
ShiftState shift;
shift.press(0);
shift.press(100);
shift.press(1000);
QCOMPARE(shift.mode(), Mode::Off);
}
void slowSecondTapTurnsOff()
{
ShiftState shift;
shift.press(0);
shift.release();
shift.press(ShiftState::DoubleTapMs + 1);
shift.release();
QCOMPARE(shift.mode(), Mode::Off);
}
void holdShiftsEveryCharacterUntilRelease()
{
ShiftState shift;
shift.press(0);
shift.characterTyped();
shift.characterTyped();
QCOMPARE(shift.mode(), Mode::Once);
shift.release();
QCOMPARE(shift.mode(), Mode::Off);
}
void automaticIgnoredWhileLocked()
{
ShiftState shift;
shift.press(0);
shift.press(100);
shift.release();
shift.setAutomatic(false);
QCOMPARE(shift.mode(), Mode::Locked);
}
void automaticCapitalizes()
{
ShiftState shift;
shift.setAutomatic(true);
QCOMPARE(shift.mode(), Mode::Once);
shift.characterTyped();
QCOMPARE(shift.mode(), Mode::Off);
}
void repeatedHintKeepsUserShift()
{
ShiftState shift;
shift.setAutomatic(false);
shift.press(0);
shift.release();
shift.setAutomatic(false); // the field re-reported
QCOMPARE(shift.mode(), Mode::Once);
}
void repeatedHintKeepsUserUnshift()
{
ShiftState shift;
shift.setAutomatic(true);
shift.press(0); // off at a sentence start
shift.release();
shift.setAutomatic(true);
QCOMPARE(shift.mode(), Mode::Off);
}
void changedHintOverridesUserShift()
{
ShiftState shift;
shift.setAutomatic(true);
shift.press(0);
shift.release();
shift.setAutomatic(false);
shift.setAutomatic(true); // e.g. backspaced to a sentence start
QCOMPARE(shift.mode(), Mode::Once);
}
void hintAppliesAgainAfterTyping()
{
ShiftState shift;
shift.setAutomatic(true);
shift.characterTyped(); // e.g. a space at a sentence start
shift.setAutomatic(true);
QCOMPARE(shift.mode(), Mode::Once);
}
};
QTEST_GUILESS_MAIN(TestShiftState)
#include "tst_shiftstate.moc"