105 lines
3.7 KiB
Go
105 lines
3.7 KiB
Go
// 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 scripts
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"reflect"
|
|
"testing"
|
|
|
|
"git.stormux.org/storm/fenrir/internal/input"
|
|
)
|
|
|
|
func TestPythonFilenameGrammar(t *testing.T) {
|
|
for _, fixture := range []struct {
|
|
name string
|
|
keys []string
|
|
}{
|
|
{"musicplayer__-__KEY_SHIFT__+__KEY_U.sh", []string{"KEY_SHIFT", "KEY_U", "KEY_SCRIPT"}},
|
|
{"KEY_A", []string{"KEY_A", "KEY_SCRIPT"}},
|
|
{"Name with spaces__-__key_ctrl__+__key_f12.py", []string{"KEY_CTRL", "KEY_F12", "KEY_SCRIPT"}},
|
|
{"explicit__-__KEY_SCRIPT__+__KEY_KPPLUS", []string{"KEY_SCRIPT", "KEY_KPPLUS"}},
|
|
{"keys__-__KEY_A__+__KEY_B", []string{"KEY_A", "KEY_B", "KEY_SCRIPT"}},
|
|
{"media__-__KEY_PLAYPAUSE", []string{"KEY_PLAYPAUSE", "KEY_SCRIPT"}},
|
|
} {
|
|
script, ok := Parse_filename(fixture.name)
|
|
if !ok || !reflect.DeepEqual(script.Keys, fixture.keys) {
|
|
t.Fatal(fixture.name, script, ok)
|
|
}
|
|
}
|
|
for _, name := range []string{"__hidden__-__KEY_A.sh", ".hidden__-__KEY_A", "bad__-__KEY_A__-__KEY_B", "bad__-__KEY_NO_SUCH_KEY", "bad__-__KEY_A__+__", "unbound.sh"} {
|
|
if _, ok := Parse_filename(name); ok {
|
|
t.Fatal("accepted invalid filename", name)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestPythonDiscoveryPrecedenceVariantsAndConflicts(t *testing.T) {
|
|
root := t.TempDir()
|
|
local, system := filepath.Join(root, "local"), filepath.Join(root, "system")
|
|
for _, directory := range []string{local, system} {
|
|
if err := os.Mkdir(directory, 0700); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
write := func(directory, name string) {
|
|
t.Helper()
|
|
if err := os.WriteFile(filepath.Join(directory, name), []byte("#!/bin/sh\n"), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
write(local, "same__-__KEY_A.sh")
|
|
write(local, "music__-__KEY_SHIFT__+__KEY_U.sh")
|
|
write(local, "music__-__KEY_SHIFT__+__KEY_X.sh")
|
|
write(system, "same__-__KEY_B.sh")
|
|
write(system, "other__-__KEY_C.sh")
|
|
write(system, "conflict__-__KEY_D.sh")
|
|
write(system, "occupied__-__KEY_C.sh")
|
|
if err := os.Symlink(filepath.Join(local, "same__-__KEY_A.sh"), filepath.Join(local, "link__-__KEY_E.sh")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.Mkdir(filepath.Join(local, "directory__-__KEY_F.sh"), 0700); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
result, problems := Discover([]string{filepath.Join(root, "missing"), local, system}, map[string]bool{input.Script_chord([]string{"KEY_D", "KEY_SCRIPT"}): true})
|
|
if len(problems) != 0 {
|
|
t.Fatal(problems)
|
|
}
|
|
var names []string
|
|
for _, script := range result {
|
|
names = append(names, filepath.Base(script.Path))
|
|
}
|
|
want := []string{"link__-__KEY_E.sh", "music__-__KEY_SHIFT__+__KEY_U.sh", "music__-__KEY_SHIFT__+__KEY_X.sh", "same__-__KEY_A.sh", "occupied__-__KEY_C.sh"}
|
|
if !reflect.DeepEqual(names, want) {
|
|
t.Fatal(names, want)
|
|
}
|
|
}
|
|
|
|
func TestPathsKeepPythonResourceRootAndDeduplicate(t *testing.T) {
|
|
home := t.TempDir()
|
|
got := Paths(home, "~/.local/stormux/fenrir", "")
|
|
want := []string{filepath.Join(home, ".local/stormux/fenrir")}
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Fatal(got, want)
|
|
}
|
|
if got := Paths(home, SystemPath, "/bundle/config/scripts"); len(got) != 3 || got[1] != SystemPath {
|
|
t.Fatal(got)
|
|
}
|
|
}
|