v0.2.0 c616855

fswatch_test.go RawHistoryFolder

1package fswatch
2
3import (
4	"context"
5	"os"
6	"path/filepath"
7	"testing"
8	"time"
9)
10
11func waitSignal(ch <-chan struct{}, d time.Duration) bool {
12	select {
13	case <-ch:
14		return true
15	case <-time.After(d):
16		return false
17	}
18}
19
20// start runs WatchDir and returns once the watch is surely in place.
21func start(t *testing.T, dir string) <-chan struct{} {
22	t.Helper()
23	ctx, cancel := context.WithCancel(context.Background())
24	t.Cleanup(cancel)
25	ch := make(chan struct{}, 1)
26	go func() { _ = WatchDir(ctx, dir, 30*time.Millisecond, ch) }()
27	time.Sleep(150 * time.Millisecond)
28	return ch
29}
30
31func TestWatchDirReportsAnyFileOfTheDirectory(t *testing.T) {
32	dir := t.TempDir()
33	ch := start(t, dir)
34	if err := os.WriteFile(filepath.Join(dir, "lib.sh"), []byte("x"), 0o644); err != nil {
35		t.Fatal(err)
36	}
37	if !waitSignal(ch, 2*time.Second) {
38		t.Fatal("a new file in the directory was not reported")
39	}
40	// An edit of an existing file, and a replacement by rename, are reported too.
41	if err := os.WriteFile(filepath.Join(dir, "lib.sh"), []byte("y"), 0o644); err != nil {
42		t.Fatal(err)
43	}
44	if !waitSignal(ch, 2*time.Second) {
45		t.Fatal("an edit was not reported")
46	}
47	tmp := filepath.Join(dir, "lib.sh.new")
48	_ = os.WriteFile(tmp, []byte("z"), 0o644)
49	waitSignal(ch, 2*time.Second) // the .new file itself
50	if err := os.Rename(tmp, filepath.Join(dir, "lib.sh")); err != nil {
51		t.Fatal(err)
52	}
53	if !waitSignal(ch, 2*time.Second) {
54		t.Fatal("a rename over a file was not reported")
55	}
56}
57
58func TestWatchDirIgnoresHiddenAndBackupFiles(t *testing.T) {
59	dir := t.TempDir()
60	ch := start(t, dir)
61	for _, name := range []string{".left.sh.swp", "left.sh~"} {
62		if err := os.WriteFile(filepath.Join(dir, name), []byte("x"), 0o644); err != nil {
63			t.Fatal(err)
64		}
65	}
66	if waitSignal(ch, 400*time.Millisecond) {
67		t.Fatal("a swap or backup file was reported")
68	}
69}
70
71func TestWatchDirWaitsForAMissingDirectory(t *testing.T) {
72	dir := filepath.Join(t.TempDir(), "later")
73	ctx, cancel := context.WithCancel(context.Background())
74	t.Cleanup(cancel)
75	ch := make(chan struct{}, 1)
76	go func() { _ = WatchDir(ctx, dir, 30*time.Millisecond, ch) }()
77	time.Sleep(100 * time.Millisecond)
78	if err := os.Mkdir(dir, 0o755); err != nil {
79		t.Fatal(err)
80	}
81	time.Sleep(2500 * time.Millisecond) // the missing directory is looked for every 2 s
82	if err := os.WriteFile(filepath.Join(dir, "a.sh"), []byte("x"), 0o644); err != nil {
83		t.Fatal(err)
84	}
85	if !waitSignal(ch, 2*time.Second) {
86		t.Fatal("a directory that appeared later was not watched")
87	}
88}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 5

Tags 4

↑↓ moveenter openesc close