package folderwatcher import ( "context" "os" "path/filepath" "sync" "testing" "time" ) func TestNewFileHandling(t *testing.T) { tmpPath, err := os.MkdirTemp("", ".folderwatcher_test") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmpPath) quitChan := make(chan struct{}) filesIn := []string{"A", "B", "C"} for i, f := range filesIn { //remap filesIn to Full Path filesIn[i] = filepath.Join(tmpPath, f) if !filepath.IsAbs(filesIn[i]) { t.Fatalf("file %s is not an absolute path", filesIn[i]) } } var filesOut []string wg := sync.WaitGroup{} conf := Config{ Folder: tmpPath, } watcher, err := NewFolderWatcher(conf, true, quitChan) if err != nil { t.Fatal(err) } go watcher.Watch(func(filePath string) (bool, error) { if !filepath.IsAbs(filePath) { t.Errorf("file %s is not an absolute path", filePath) } filesOut = append(filesOut, filePath) wg.Done() return true, nil }, func(s string, err error) { }) for _, f := range filesIn { wg.Add(1) _ = os.WriteFile(f, []byte{0}, os.ModePerm) } finishedChan := make(chan struct{}) go func() { wg.Wait() finishedChan <- struct{}{} }() ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Second) defer ctxCancel() select { case <-finishedChan: case <-ctx.Done(): t.Error(ctx.Err()) } quitChan <- struct{}{} if len(filesOut) != len(filesIn) { t.Errorf("filesOut length %d != %d", len(filesOut), len(filesIn)) } for _, f := range filesIn { if !Contains(filesOut, f) { t.Errorf("File %s not found in %s", f, filesOut) } } } func TestOldFileHandling(t *testing.T) { tmpPath, err := os.MkdirTemp("", ".folderwatcher_test") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmpPath) quitChan := make(chan struct{}) filesIn := []string{"A", "B", "C"} for i, f := range filesIn { //remap filesIn to Full Path filesIn[i] = filepath.Join(tmpPath, f) if !filepath.IsAbs(filesIn[i]) { t.Fatalf("file %s is not an absolute path", filesIn[i]) } } var filesOut []string wg := sync.WaitGroup{} conf := Config{ Folder: tmpPath, } for _, f := range filesIn { wg.Add(1) _ = os.WriteFile(f, []byte{0}, os.ModePerm) } watcher, err := NewFolderWatcher(conf, true, quitChan) if err != nil { t.Fatal(err) } go watcher.Watch(func(filePath string) (bool, error) { if !filepath.IsAbs(filePath) { t.Errorf("file %s is not an absolute path", filePath) } filesOut = append(filesOut, filePath) wg.Done() return true, nil }, func(s string, err error) { }) finishedChan := make(chan struct{}) go func() { wg.Wait() finishedChan <- struct{}{} }() ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Second) defer ctxCancel() select { case <-finishedChan: case <-ctx.Done(): t.Error(ctx.Err()) } quitChan <- struct{}{} if len(filesOut) != len(filesIn) { t.Errorf("filesOut length %d != %d", len(filesOut), len(filesIn)) } for _, f := range filesIn { if !Contains(filesOut, f) { t.Errorf("File %s not found in %s", f, filesOut) } } } func TestOldAndNewFileHandling(t *testing.T) { tmpPath, err := os.MkdirTemp("", ".folderwatcher_test") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmpPath) quitChan := make(chan struct{}) filesIn := []string{"A", "B", "C"} for i, f := range filesIn { //remap filesIn to Full Path filesIn[i] = filepath.Join(tmpPath, f) if !filepath.IsAbs(filesIn[i]) { t.Fatalf("file %s is not an absolute path", filesIn[i]) } } filesInRunning := []string{"D", "E", "F"} for i, f := range filesInRunning { //remap filesIn to Full Path filesInRunning[i] = filepath.Join(tmpPath, f) if !filepath.IsAbs(filesInRunning[i]) { t.Fatalf("file %s is not an absolute path", filesInRunning[i]) } } var filesOut []string wg := sync.WaitGroup{} conf := Config{ Folder: tmpPath, } for _, f := range filesIn { wg.Add(1) _ = os.WriteFile(f, []byte{0}, os.ModePerm) } watcher, err := NewFolderWatcher(conf, true, quitChan) if err != nil { t.Fatal(err) } go watcher.Watch(func(filePath string) (bool, error) { if !filepath.IsAbs(filePath) { t.Errorf("file %s is not an absolute path", filePath) } filesOut = append(filesOut, filePath) wg.Done() return true, nil }, func(s string, err error) { }) for _, f := range filesInRunning { wg.Add(1) filesIn = append(filesIn, f) _ = os.WriteFile(f, []byte{0}, os.ModePerm) } finishedChan := make(chan struct{}) go func() { wg.Wait() finishedChan <- struct{}{} }() ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Second) defer ctxCancel() select { case <-finishedChan: case <-ctx.Done(): t.Error(ctx.Err()) } quitChan <- struct{}{} if len(filesOut) != len(filesIn) { t.Errorf("filesOut length %d != %d", len(filesOut), len(filesIn)) } for _, f := range filesIn { if !Contains(filesOut, f) { t.Errorf("File %s not found in %s", f, filesOut) } } } func TestOldAndNewFileHandlingWithoutExisting(t *testing.T) { tmpPath, err := os.MkdirTemp("", ".folderwatcher_test") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmpPath) quitChan := make(chan struct{}) filesIn := []string{"A", "B", "C"} for i, f := range filesIn { //remap filesIn to Full Path filesIn[i] = filepath.Join(tmpPath, f) if !filepath.IsAbs(filesIn[i]) { t.Fatalf("file %s is not an absolute path", filesIn[i]) } } filesInRunning := []string{"D", "E", "F"} for i, f := range filesInRunning { //remap filesInRunning to Full Path filesInRunning[i] = filepath.Join(tmpPath, f) if !filepath.IsAbs(filesInRunning[i]) { t.Fatalf("file %s is not an absolute path", filesInRunning[i]) } } var filesOut []string wg := sync.WaitGroup{} conf := Config{ Folder: tmpPath, } for _, f := range filesIn { _ = os.WriteFile(f, []byte{0}, os.ModePerm) } watcher, err := NewFolderWatcher(conf, false, quitChan) if err != nil { t.Fatal(err) } go watcher.Watch(func(filePath string) (bool, error) { if !filepath.IsAbs(filePath) { t.Errorf("file %s is not an absolute path", filePath) } filesOut = append(filesOut, filePath) wg.Done() return true, nil }, func(s string, err error) { }) for _, f := range filesInRunning { wg.Add(1) _ = os.WriteFile(f, []byte{0}, os.ModePerm) } finishedChan := make(chan struct{}) go func() { wg.Wait() finishedChan <- struct{}{} }() ctx, ctxCancel := context.WithTimeout(context.Background(), 10*time.Second) defer ctxCancel() select { case <-finishedChan: case <-ctx.Done(): t.Error(ctx.Err()) } quitChan <- struct{}{} if len(filesOut) != len(filesInRunning) { t.Errorf("filesOut length %d != %d", len(filesOut), len(filesInRunning)) } for _, f := range filesInRunning { if !Contains(filesOut, f) { t.Errorf("File %s not found in %s", f, filesOut) } } for _, f := range filesIn { if Contains(filesOut, f) { t.Errorf("File %s found in %s", f, filesOut) } } } func Contains[T comparable](slice []T, item T) bool { for _, v := range slice { if v == item { return true } } return false }