After commit c018f5fd29 Fenrir is being switched over to go. If you do not want to be part of the testing process, please switch to master.
This commit is contained in:
1 parent
c018f5fd29
commit
0e50de4c76
1047 files changed
+58364
-63747
No files matched your search
@@ -0,0 +1,186 @@
|
||||
// Fenrir console screen reader.
|
||||
// Copyright (c) 2026 Storm Dragon
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
// more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <https://www.gnu.org/licenses/gpl-3.0.html>.
|
||||
|
||||
package input
|
||||
|
||||
import (
|
||||
"git.stormux.org/storm/fenrir/internal/command"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestReviewAndReleaseOrder(t *testing.T) {
|
||||
router := desktop_router(t)
|
||||
if got := router.Key(1, KeyInsert, 1, false, false); got.Forward || got.Interrupt {
|
||||
t.Fatalf("modifier: %+v", got)
|
||||
}
|
||||
if got := router.Key(2, KeyKP5, 1, false, false); got.Forward || got.Command != command.ReadScreen {
|
||||
t.Fatalf("cross-device chord: %+v", got)
|
||||
}
|
||||
router.Key(1, KeyInsert, 0, false, false)
|
||||
if got := router.Key(2, KeyKP5, 2, true, false); got.Forward || got.Command != "" {
|
||||
t.Fatalf("held chord changed after modifier release: %+v", got)
|
||||
}
|
||||
if got := router.Key(2, KeyKP5, 0, true, false); got.Forward {
|
||||
t.Fatalf("consumed release leaked: %+v", got)
|
||||
}
|
||||
if got := router.Key(2, KeyKP5, 1, false, false); got.Command != command.CurrentWord {
|
||||
t.Fatalf("bare review: %+v", got)
|
||||
}
|
||||
if got := router.Key(2, KeyKP5, 2, false, false); got.Command != command.CurrentWord {
|
||||
t.Fatalf("repeat: %+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTypingNumLockAndControl(t *testing.T) {
|
||||
router := desktop_router(t)
|
||||
if got := router.Key(1, KeyKP0, 1, true, false); !got.Forward || !got.Interrupt {
|
||||
t.Fatalf("numeric zero must interrupt like other typing: %+v", got)
|
||||
}
|
||||
router.Key(1, KeyKP0, 0, true, false)
|
||||
if got := router.Key(1, KeyKP1, 1, true, false); !got.Forward || !got.Interrupt || got.Command != "" {
|
||||
t.Fatalf("numeric press: %+v", got)
|
||||
}
|
||||
if got := router.Key(1, KeyKP1, 0, false, false); !got.Forward || got.Interrupt {
|
||||
t.Fatalf("numeric release after NumLock changed: %+v", got)
|
||||
}
|
||||
if got := router.Key(1, KeyCtrl, 1, false, false); !got.Forward || !got.Interrupt {
|
||||
t.Fatalf("control must stop speech and reach application: %+v", got)
|
||||
}
|
||||
if got := router.Key(1, KeyKP4, 1, false, false); !got.Forward || got.Command != "" {
|
||||
t.Fatalf("application control chord: %+v", got)
|
||||
}
|
||||
if got := router.Key(1, KeyShift, 1, false, false); !got.Forward || got.Interrupt {
|
||||
t.Fatalf("shift must not interrupt: %+v", got)
|
||||
}
|
||||
if got := router.Key(1, 30, 1, false, false); !got.Forward || !got.Interrupt {
|
||||
t.Fatalf("ordinary letter: %+v", got)
|
||||
}
|
||||
if got := router.Key(1, 30, 0, false, false); !got.Forward || got.Interrupt {
|
||||
t.Fatalf("letter release: %+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPassNextChordAndReset(t *testing.T) {
|
||||
router := desktop_router(t)
|
||||
router.Pass_next()
|
||||
if got := router.Key(1, KeyInsert, 1, false, false); !got.Forward {
|
||||
t.Fatal("pass-next swallowed Insert")
|
||||
}
|
||||
if got := router.Key(1, KeyQ, 1, false, false); !got.Forward || got.Command != "" {
|
||||
t.Fatalf("pass-next quit chord: %+v", got)
|
||||
}
|
||||
router.Key(1, KeyInsert, 0, false, false)
|
||||
router.Key(1, KeyQ, 0, false, false)
|
||||
router.Key(1, KeyInsert, 1, false, false)
|
||||
if got := router.Key(1, KeyQ, 1, false, false); got.Forward || got.Command != command.Quit {
|
||||
t.Fatalf("reader chord after pass-next: %+v", got)
|
||||
}
|
||||
router.Reset()
|
||||
if got := router.Key(1, 30, 0, false, false); got.Forward {
|
||||
t.Fatal("orphan release after handoff")
|
||||
}
|
||||
if got := router.Key(1, KeyKP8, 2, false, false); got.Command != "" {
|
||||
t.Fatal("orphan repeat after handoff")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncAndDisconnectDoNotRunCommands(t *testing.T) {
|
||||
router := desktop_router(t)
|
||||
router.Key(1, KeyInsert, 1, false, true)
|
||||
if got := router.Key(1, KeyQ, 1, false, true); got.Forward || got.Command != "" || got.Interrupt {
|
||||
t.Fatalf("sync ran command: %+v", got)
|
||||
}
|
||||
router.Drop(1)
|
||||
if got := router.Key(2, KeyQ, 1, false, false); !got.Forward || got.Command != "" {
|
||||
t.Fatalf("disconnected modifier stuck: %+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBareKeypadEnterIsConsumed(t *testing.T) {
|
||||
router := desktop_router(t)
|
||||
if got := router.Key(0, KeyKPEnter, 1, false, false); got.Command != "temp_disable_speech" || got.Forward || !got.Interrupt {
|
||||
t.Fatal("keypad Enter did not temporarily silence speech", got)
|
||||
}
|
||||
if got := router.Key(0, KeyKPEnter, 2, false, false); got.Command != "" || got.Forward {
|
||||
t.Fatal("held keypad Enter repeated or leaked", got)
|
||||
}
|
||||
if got := router.Key(0, KeyKPEnter, 0, true, false); got.Forward {
|
||||
t.Fatal("keypad Enter release leaked after NumLock change", got)
|
||||
}
|
||||
if got := router.Key(0, KeyKPEnter, 1, true, false); !got.Forward || got.Command != "" {
|
||||
t.Fatal("NumLock-on keypad Enter was consumed", got)
|
||||
}
|
||||
router.Reset()
|
||||
router.Key(0, KeyInsert, 1, false, false)
|
||||
if got := router.Key(0, KeyKPEnter, 1, false, false); got.Command != command.AutoRead || got.Forward {
|
||||
t.Fatal("Fenrir+keypad Enter lost automatic-reading toggle", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestKeypressExcludesRepeatsReleasesAndStateRepair(t *testing.T) {
|
||||
for _, key := range []uint16{KeyKPEnter, KeyKP8, KeyShift, KeyInsert, KeyF} {
|
||||
for _, capture := range []bool{false, true} {
|
||||
router := desktop_router(t)
|
||||
router.Capture(capture)
|
||||
if got := router.Key(0, key, 1, false, false); !got.Keypress {
|
||||
t.Fatal("fresh press not reported", key, capture, got)
|
||||
}
|
||||
for _, event := range []struct {
|
||||
value int32
|
||||
sync bool
|
||||
}{{2, false}, {1, false}, {0, false}, {1, true}, {0, true}, {2, false}} {
|
||||
if got := router.Key(0, key, event.value, false, event.sync); got.Keypress {
|
||||
t.Fatal("non-press reported as fresh key", key, capture, event, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTypingMetadataExcludesCommandsNavigationAndShortcuts(t *testing.T) {
|
||||
for _, testCase := range []struct {
|
||||
key uint16
|
||||
modifier uint16
|
||||
numLock, typing, boundary bool
|
||||
}{
|
||||
{30, 0, false, true, false}, {30, KeyShift, false, true, false},
|
||||
{30, KeyRightAlt, false, true, false}, {30, KeyCtrl, false, false, false},
|
||||
{30, KeyAlt, false, false, false}, {KeySpace, 0, false, true, true},
|
||||
{KeyKP8, 0, false, false, false}, {KeyKP8, 0, true, true, false},
|
||||
{KeyRight, 0, false, false, false}, {KeyBackspace, 0, false, false, false},
|
||||
{KeyTab, 0, false, false, false}, {KeyF, KeyInsert, false, false, false},
|
||||
} {
|
||||
router := desktop_router(t)
|
||||
if testCase.modifier != 0 {
|
||||
router.Key(0, testCase.modifier, 1, testCase.numLock, false)
|
||||
}
|
||||
for _, value := range []int32{1, 2} {
|
||||
got := router.Key(0, testCase.key, value, testCase.numLock, false)
|
||||
if got.Typing != testCase.typing || got.WordBoundary != testCase.boundary {
|
||||
t.Fatal("wrong typing classification", testCase, value, got)
|
||||
}
|
||||
}
|
||||
for _, event := range []struct {
|
||||
value int32
|
||||
sync bool
|
||||
}{{0, false}, {1, true}, {0, true}} {
|
||||
if got := router.Key(0, testCase.key, event.value, testCase.numLock, event.sync); got.Typing || got.WordBoundary {
|
||||
t.Fatal("release or state repair became typing", testCase, event, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user