watch/watch_test.go

153 lines
3.3 KiB
Go
Raw Permalink Normal View History

package watch_test
import (
"os"
"path/filepath"
"sync/atomic"
"testing"
"time"
"apigo.cc/go/file"
"apigo.cc/go/watch"
)
func TestWatch(t *testing.T) {
testDir := "test_watch"
_ = os.RemoveAll(testDir)
_ = os.MkdirAll(testDir, 0755)
defer os.RemoveAll(testDir)
events := make(chan *watch.Event, 10)
config := watch.Config{
Paths: []string{testDir},
Types: []string{".txt"},
}
w, err := watch.Start(config, func(e *watch.Event) {
events <- e
})
if err != nil {
t.Fatal(err)
}
defer w.Stop()
// 1. 测试创建文件
txtFile, _ := filepath.Abs(filepath.Join(testDir, "test.txt"))
_ = file.Write(txtFile, "hello")
select {
case e := <-events:
if e.Type != watch.Create || e.Path != txtFile {
t.Errorf("expected create event for %s, got %v", txtFile, e)
}
case <-time.After(200 * time.Millisecond):
t.Fatal("timeout waiting for create event")
}
// 2. 测试排除类型
config2 := watch.Config{
Paths: []string{testDir},
ExcludeTypes: []string{".tmp"},
}
events2 := make(chan *watch.Event, 10)
w2, _ := watch.Start(config2, func(e *watch.Event) {
events2 <- e
})
defer w2.Stop()
tmpFile := filepath.Join(testDir, "test.tmp")
_ = file.Write(tmpFile, "temp")
select {
case e := <-events2:
t.Errorf("should not receive event for .tmp file, got %v", e)
case <-time.After(100 * time.Millisecond):
// OK
}
// 3. 测试模糊排除 (Gitignore 语义)
config3 := watch.Config{
Paths: []string{testDir},
Excludes: []string{"**/node_modules/**", "*.log"},
}
events3 := make(chan *watch.Event, 10)
w3, _ := watch.Start(config3, func(e *watch.Event) {
events3 <- e
})
defer w3.Stop()
logFile, _ := filepath.Abs(filepath.Join(testDir, "test.log"))
_ = file.Write(logFile, "log")
nodeDir := filepath.Join(testDir, "node_modules")
_ = os.MkdirAll(nodeDir, 0755)
_ = file.Write(filepath.Join(nodeDir, "index.js"), "js")
select {
case e := <-events3:
t.Errorf("should not receive event for excluded path/file, got %v", e.Path)
case <-time.After(100 * time.Millisecond):
// OK
}
}
func TestDebounce(t *testing.T) {
testDir := "test_debounce"
_ = os.RemoveAll(testDir)
_ = os.MkdirAll(testDir, 0755)
defer os.RemoveAll(testDir)
var count int32
config := watch.Config{
Paths: []string{testDir},
Debounce: 100 * time.Millisecond,
}
w, _ := watch.Start(config, func(e *watch.Event) {
if e.Type == watch.Change {
atomic.AddInt32(&count, 1)
}
})
defer w.Stop()
targetFile := filepath.Join(testDir, "change.txt")
_ = file.Write(targetFile, "v1")
// 连续写入
for i := 0; i < 5; i++ {
_ = file.Write(targetFile, "v2")
time.Sleep(10 * time.Millisecond)
}
// 等待防抖结束
time.Sleep(200 * time.Millisecond)
finalCount := atomic.LoadInt32(&count)
if finalCount != 1 {
t.Errorf("expected 1 change event after debounce, got %d", finalCount)
}
}
func TestEasyStart(t *testing.T) {
testDir := "test_easy"
_ = os.RemoveAll(testDir)
_ = os.MkdirAll(testDir, 0755)
defer os.RemoveAll(testDir)
done := make(chan bool)
_, _ = watch.EasyStart(testDir, func(path string, et watch.EventType) {
if et == watch.Create {
done <- true
}
})
_ = file.Write(filepath.Join(testDir, "easy.txt"), "easy")
select {
case <-done:
// OK
case <-time.After(200 * time.Millisecond):
t.Fatal("timeout waiting for easy event")
}
}