// Copyright (c) 2026 Storm Dragon // SPDX-License-Identifier: GPL-3.0-or-later package input import ( "os" "testing" "time" "git.stormux.org/storm/fenrir/internal/command" ) func TestTimeDateDoublePress(t *testing.T) { for _, layout := range []string{"desktop", "laptop"} { for _, scenario := range []string{"double", "expired", "repeat", "modifier release", "other key", "reset", "capture", "sync", "unchanged sync", "drop", "other device", "pass next"} { t.Run(layout+"/"+scenario, func(t *testing.T) { data, err := os.ReadFile("../../config/keyboard/" + layout + ".toml") if err != nil { t.Fatal(err) } bindings, err := Decode_bindings(data) if err != nil { t.Fatal(err) } router, err := New_router(bindings) if err != nil { t.Fatal(err) } now := time.Unix(1000, 0) router.now = func() time.Time { return now } const keyT = 20 router.Key(1, KeyInsert, 1, false, false) if got := router.Key(1, keyT, 1, false, false); got.Command != command.Time || got.Forward || !got.Interrupt { t.Fatal(got) } if got := router.Key(1, keyT, 2, false, false); got.Command != "" || got.Forward { t.Fatal("repeat became date", got) } if got := router.Key(1, keyT, 0, false, false); got.Forward { t.Fatal("release leaked", got) } now = now.Add(100 * time.Millisecond) want, device := command.Time, 1 switch scenario { case "double", "repeat": want = command.Date case "expired": now = now.Add(101 * time.Millisecond) case "modifier release": router.Key(1, KeyInsert, 0, false, false) router.Key(1, KeyInsert, 1, false, false) want = command.Date case "other key": router.Key(1, KeyF, 1, false, false) router.Key(1, KeyF, 0, false, false) case "reset": router.Reset() router.Key(1, KeyInsert, 1, false, false) case "capture": router.Capture(true) router.Capture(false) case "sync": router.Key(1, KeyShift, 1, false, true) router.Key(1, KeyShift, 0, false, true) case "unchanged sync": router.Key(1, KeyShift, 0, false, true) router.Key(1, KeyInsert, 1, false, true) want = command.Date case "drop": router.Drop(1) router.Key(1, KeyInsert, 1, false, false) case "other device": device = 2 case "pass next": router.Pass_next() if got := router.Key(1, keyT, 1, false, false); !got.Forward || got.Command != "" { t.Fatal(got) } return } if got := router.Key(device, keyT, 1, false, false); got.Command != want || got.Forward { t.Fatal(got, "want", want) } if want == command.Date { router.Key(device, keyT, 0, false, false) if got := router.Key(device, keyT, 1, false, false); got.Command != command.Time { t.Fatal("third press", got) } } }) } } } func TestDoubleCommandValidationAndRemapping(t *testing.T) { for _, doubleCommand := range []command.ID{command.Date, "unknown"} { router, err := New_router(Layout{Bindings: []Binding{{Name: "Clock", Keys: []string{"FENRIR", "G"}, Command: command.Time, DoubleCommand: doubleCommand}}}) if doubleCommand == "unknown" { if err == nil { t.Fatal("unknown double command accepted") } continue } if err != nil { t.Fatal(err) } router.Key(1, KeyInsert, 1, false, false) if got := router.Key(1, 34, 1, false, false); got.Command != command.Time { t.Fatal(got) } router.Key(1, 34, 0, false, false) if got := router.Key(1, 34, 1, false, false); got.Command != command.Date { t.Fatal(got) } router.Reset() if got := router.Key(1, 20, 1, false, false); !got.Forward || got.Command != "" { t.Fatal("ordinary t intercepted", got) } } }