package pool import ( "testing" "time" "pad/internal/io/pool/mock" ) func TestReadDirTask_Execute_Success(t *testing.T) { fs := mock.NewFileSystem() fs.CreateDir("/test/dir") fs.CreateFile("/test/dir/a.txt", []byte("a")) fs.CreateFile("/test/dir/b.txt", []byte("b")) task := NewReadDirTask("/test/dir", fs) result := task.Execute() if !result.IsSuccess() { t.Fatalf("Expected success, got error: %v", result.Error) } if result.TaskType != TypeReadDir { t.Errorf("TaskType = %v, want %v", result.TaskType, TypeReadDir) } if result.TaskID == "" { t.Error("TaskID should not be empty") } entries, ok := result.Data.([]mock.DirEntry) if !ok { t.Fatalf("Data is not []mock.DirEntry, got %T", result.Data) } if len(entries) != 2 { t.Errorf("Expected 2 entries, got %d", len(entries)) } } func TestReadDirTask_Execute_NotFound(t *testing.T) { fs := mock.NewFileSystem() task := NewReadDirTask("/nonexistent", fs) result := task.Execute() if result.IsSuccess() { t.Fatal("Expected failure for nonexistent directory") } if result.Error == nil { t.Error("Expected error, got nil") } } func TestBuildIndexTask_Execute(t *testing.T) { fs := mock.NewFileSystem() fs.CreateDir("/test/dir") fs.CreateFile("/test/dir/file.txt", []byte("content")) task := NewBuildIndexTask("/test/dir", fs) result := task.Execute() if !result.IsSuccess() { t.Fatalf("Expected success, got error: %v", result.Error) } if result.TaskType != TypeBuildIndex { t.Errorf("TaskType = %v, want %v", result.TaskType, TypeBuildIndex) } } func TestLoadPagesTask_Execute(t *testing.T) { fs := mock.NewFileSystem() task := NewLoadPagesTask("/test/dir", []int{0, 1, 2}, fs) result := task.Execute() if !result.IsSuccess() { t.Fatalf("Expected success, got error: %v", result.Error) } if result.TaskType != TypeLoadPages { t.Errorf("TaskType = %v, want %v", result.TaskType, TypeLoadPages) } pages, ok := result.Data.([]int) if !ok { t.Fatalf("Data is not []int, got %T", result.Data) } if len(pages) != 3 { t.Errorf("Expected 3 pages, got %d", len(pages)) } } func TestReadFileTask_Execute_Success(t *testing.T) { fs := mock.NewFileSystem() fs.CreateFile("/test/file.txt", []byte("hello world")) task := NewReadFileTask("/test/file.txt", fs) result := task.Execute() if !result.IsSuccess() { t.Fatalf("Expected success, got error: %v", result.Error) } if result.TaskType != TypeReadFile { t.Errorf("TaskType = %v, want %v", result.TaskType, TypeReadFile) } content, ok := result.Data.([]byte) if !ok { t.Fatalf("Data is not []byte, got %T", result.Data) } if string(content) != "hello world" { t.Errorf("Content = %q, want %q", string(content), "hello world") } } func TestReadFileTask_Execute_NotFound(t *testing.T) { fs := mock.NewFileSystem() task := NewReadFileTask("/nonexistent.txt", fs) result := task.Execute() if result.IsSuccess() { t.Fatal("Expected failure for nonexistent file") } } func TestWriteFileTask_Execute(t *testing.T) { fs := mock.NewFileSystem() fs.CreateFile("/test/file.txt", []byte("original")) task := NewWriteFileTask("/test/file.txt", []byte("updated"), fs) result := task.Execute() if !result.IsSuccess() { t.Fatalf("Expected success, got error: %v", result.Error) } if result.TaskType != TypeWriteFile { t.Errorf("TaskType = %v, want %v", result.TaskType, TypeWriteFile) } // Verify file was actually written content, err := fs.ReadFile("/test/file.txt") if err != nil { t.Fatalf("ReadFile failed: %v", err) } if string(content) != "updated" { t.Errorf("File content = %q, want %q", string(content), "updated") } } func TestWriteFileTask_Execute_NotFound(t *testing.T) { fs := mock.NewFileSystem() task := NewWriteFileTask("/nonexistent.txt", []byte("data"), fs) result := task.Execute() if result.IsSuccess() { t.Fatal("Expected failure for nonexistent file") } } func TestSaveStateTask_Execute(t *testing.T) { fs := mock.NewFileSystem() fs.CreateFile("/test/state.json", []byte("{}")) task := NewSaveStateTask("/test/state.json", []byte(`{"key":"value"}`), fs) result := task.Execute() if !result.IsSuccess() { t.Fatalf("Expected success, got error: %v", result.Error) } if result.TaskType != TypeSaveState { t.Errorf("TaskType = %v, want %v", result.TaskType, TypeSaveState) } // Verify state was saved content, err := fs.ReadFile("/test/state.json") if err != nil { t.Fatalf("ReadFile failed: %v", err) } if string(content) != `{"key":"value"}` { t.Errorf("State content = %q, want %q", string(content), `{"key":"value"}`) } } func TestSaveUndoTask_Execute(t *testing.T) { fs := mock.NewFileSystem() fs.CreateFile("/test/undo.json", []byte("[]")) task := NewSaveUndoTask("/test/undo.json", []byte(`[{"type":"insert"}]`), fs) result := task.Execute() if !result.IsSuccess() { t.Fatalf("Expected success, got error: %v", result.Error) } if result.TaskType != TypeSaveUndo { t.Errorf("TaskType = %v, want %v", result.TaskType, TypeSaveUndo) } } func TestTask_Priority_ReadDir(t *testing.T) { fs := mock.NewFileSystem() task := NewReadDirTask("/test", fs) if task.Priority() != HighPriority { t.Errorf("Priority = %v, want %v", task.Priority(), HighPriority) } } func TestTask_Priority_BuildIndex(t *testing.T) { fs := mock.NewFileSystem() task := NewBuildIndexTask("/test", fs) if task.Priority() != HighPriority { t.Errorf("Priority = %v, want %v", task.Priority(), HighPriority) } } func TestTask_Priority_LoadPages(t *testing.T) { fs := mock.NewFileSystem() task := NewLoadPagesTask("/test", []int{0}, fs) if task.Priority() != HighPriority { t.Errorf("Priority = %v, want %v", task.Priority(), HighPriority) } } func TestTask_Priority_ReadFile(t *testing.T) { fs := mock.NewFileSystem() task := NewReadFileTask("/test/file.txt", fs) if task.Priority() != HighPriority { t.Errorf("Priority = %v, want %v", task.Priority(), HighPriority) } } func TestTask_Priority_WriteFile(t *testing.T) { fs := mock.NewFileSystem() task := NewWriteFileTask("/test/file.txt", []byte("data"), fs) if task.Priority() != LowPriority { t.Errorf("Priority = %v, want %v", task.Priority(), LowPriority) } } func TestTask_Priority_SaveState(t *testing.T) { fs := mock.NewFileSystem() task := NewSaveStateTask("/test/state.json", []byte("{}"), fs) if task.Priority() != LowPriority { t.Errorf("Priority = %v, want %v", task.Priority(), LowPriority) } } func TestTask_Priority_SaveUndo(t *testing.T) { fs := mock.NewFileSystem() task := NewSaveUndoTask("/test/undo.json", []byte("[]"), fs) if task.Priority() != LowPriority { t.Errorf("Priority = %v, want %v", task.Priority(), LowPriority) } } func TestTask_DirPath(t *testing.T) { fs := mock.NewFileSystem() task := NewReadDirTask("/test/dir", fs) if task.DirPath() != "/test/dir" { t.Errorf("DirPath = %q, want %q", task.DirPath(), "/test/dir") } task2 := NewReadFileTask("/test/dir/file.txt", fs) if task2.DirPath() != "/test/dir" { t.Errorf("DirPath = %q, want %q", task2.DirPath(), "/test/dir") } } func TestTask_TaskID_Unique(t *testing.T) { fs := mock.NewFileSystem() task1 := NewReadDirTask("/test/dir", fs) task2 := NewReadDirTask("/test/dir", fs) if task1.TaskID() == task2.TaskID() { t.Error("Task IDs should be unique") } } func TestTask_TaskType_String(t *testing.T) { tests := []struct { taskType TaskType want string }{ {TypeReadDir, "read_dir"}, {TypeBuildIndex, "build_index"}, {TypeLoadIndex, "load_index"}, {TypeLoadPages, "load_pages"}, {TypeStatDir, "stat_dir"}, {TypeReadFile, "read_file"}, {TypeWriteFile, "write_file"}, {TypeStatFile, "stat_file"}, {TypeWriteCache, "write_cache"}, {TypeReadCache, "read_cache"}, {TypeInvalidate, "invalidate_cache"}, {TypeSaveState, "save_state"}, {TypeSaveUndo, "save_undo"}, } for _, tt := range tests { if string(tt.taskType) != tt.want { t.Errorf("TaskType %v = %q, want %q", tt.taskType, string(tt.taskType), tt.want) } } } func TestPriority_String(t *testing.T) { tests := []struct { priority Priority want string }{ {HighPriority, "high"}, {LowPriority, "low"}, } for _, tt := range tests { if tt.priority.String() != tt.want { t.Errorf("Priority %v.String() = %q, want %q", tt.priority, tt.priority.String(), tt.want) } } } func TestReadFileTask_WithDelay(t *testing.T) { fs := mock.NewFileSystem() fs.SetDelay(10 * time.Millisecond) fs.CreateFile("/test/delayed.txt", []byte("delayed")) task := NewReadFileTask("/test/delayed.txt", fs) start := time.Now() result := task.Execute() elapsed := time.Since(start) if !result.IsSuccess() { t.Fatalf("Expected success, got error: %v", result.Error) } if elapsed < 5*time.Millisecond { t.Errorf("Expected delay ~10ms, got %v", elapsed) } } func TestCreateFile_WithDelay(t *testing.T) { fs := mock.NewFileSystem() fs.SetDelay(20 * time.Millisecond) start := time.Now() err := fs.CreateFile("/test/delayed.txt", []byte("test")) elapsed := time.Since(start) if err != nil { t.Fatalf("CreateFile failed: %v", err) } if elapsed < 15*time.Millisecond { t.Errorf("Expected delay ~20ms, got %v", elapsed) } } func TestWriteFile_WithDelay(t *testing.T) { fs := mock.NewFileSystem() fs.SetDelay(15 * time.Millisecond) fs.CreateFile("/test/delayed.txt", []byte("original")) start := time.Now() err := fs.WriteFile("/test/delayed.txt", []byte("updated")) elapsed := time.Since(start) if err != nil { t.Fatalf("WriteFile failed: %v", err) } if elapsed < 10*time.Millisecond { t.Errorf("Expected delay ~15ms, got %v", elapsed) } } func TestDeleteFile_WithDelay(t *testing.T) { fs := mock.NewFileSystem() fs.SetDelay(10 * time.Millisecond) fs.CreateFile("/test/delayed.txt", []byte("test")) start := time.Now() err := fs.DeleteFile("/test/delayed.txt") elapsed := time.Since(start) if err != nil { t.Fatalf("DeleteFile failed: %v", err) } if elapsed < 5*time.Millisecond { t.Errorf("Expected delay ~10ms, got %v", elapsed) } } func TestReadDir_WithDelay(t *testing.T) { fs := mock.NewFileSystem() fs.SetDelay(10 * time.Millisecond) fs.CreateDir("/test/dir") fs.CreateFile("/test/dir/a.txt", []byte("a")) start := time.Now() _, err := fs.ReadDir("/test/dir") elapsed := time.Since(start) if err != nil { t.Fatalf("ReadDir failed: %v", err) } if elapsed < 5*time.Millisecond { t.Errorf("Expected delay ~10ms, got %v", elapsed) } }