package preproc import ( "os" "path/filepath" "testing" ) func TestDiskFileReader_ReadLines_LibraryIncludes(t *testing.T) { origPath := os.Getenv("C65LIBPATH") defer os.Setenv("C65LIBPATH", origPath) libPath, _ := filepath.Abs("filereader_mocks/lib") os.Setenv("C65LIBPATH", libPath) // Now create reader reader := NewDiskFileReader() tests := []struct { name string includeSpec string wantErr bool }{ { name: "simple library include", includeSpec: "", wantErr: false, }, { name: "nested library include", includeSpec: "", wantErr: false, }, { name: "missing library file", includeSpec: "", wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { lines, _, err := reader.ReadLines(tt.includeSpec, "") if (err != nil) != tt.wantErr { t.Errorf("ReadLines() error = %v, wantErr %v", err, tt.wantErr) return } if !tt.wantErr && len(lines) == 0 { t.Error("expected lines, got empty slice") } }) } } func TestDiskFileReader_ReadLines_LibraryWithoutEnv(t *testing.T) { origPath := os.Getenv("C65LIBPATH") defer os.Setenv("C65LIBPATH", origPath) os.Setenv("C65LIBPATH", "") // Now create reader reader := NewDiskFileReader() _, _, err := reader.ReadLines("", "") if err == nil { t.Error("expected error when C65LIBPATH not set") } } func TestDiskFileReader_ReadLines_RelativeIncludes(t *testing.T) { reader := NewDiskFileReader() appDir, _ := filepath.Abs("filereader_mocks/app") tests := []struct { name string includeSpec string currentDir string wantErr bool }{ { name: "bare include", includeSpec: "test_app.c65", currentDir: appDir, wantErr: false, }, { name: "quoted include", includeSpec: `"test_app.c65"`, currentDir: appDir, wantErr: false, }, { name: "single quoted include", includeSpec: "'test_app.c65'", currentDir: appDir, wantErr: false, }, { name: "nested relative include", includeSpec: "appsub/test_appsub.c65", currentDir: appDir, wantErr: false, }, { name: "missing file", includeSpec: "notfound.c65", currentDir: appDir, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { lines, _, err := reader.ReadLines(tt.includeSpec, tt.currentDir) if (err != nil) != tt.wantErr { t.Errorf("ReadLines() error = %v, wantErr %v", err, tt.wantErr) return } if !tt.wantErr && len(lines) == 0 { t.Error("expected lines, got empty slice") } }) } } func TestDiskFileReader_ReadLines_Cache(t *testing.T) { reader := NewDiskFileReader() appDir, _ := filepath.Abs("filereader_mocks/app") // First read lines1, _, err := reader.ReadLines("test_app.c65", appDir) if err != nil { t.Fatalf("first read failed: %v", err) } // Second read (should hit cache) lines2, _, err := reader.ReadLines("test_app.c65", appDir) if err != nil { t.Fatalf("second read failed: %v", err) } // Verify same slice (from cache) if len(lines1) != len(lines2) { t.Errorf("cache returned different length: %d vs %d", len(lines1), len(lines2)) } // Verify cache was actually used (check map size) if len(reader.cache) != 1 { t.Errorf("expected 1 cache entry, got %d", len(reader.cache)) } } func TestDiskFileReader_ReadLines_EmptyFile(t *testing.T) { reader := NewDiskFileReader() appDir, _ := filepath.Abs("filereader_mocks/app") lines, _, err := reader.ReadLines("empty.c65", appDir) if err != nil { t.Fatalf("failed to read empty file: %v", err) } // Empty file still returns slice with one empty string if len(lines) != 1 { t.Errorf("empty file: expected 1 line, got %d", len(lines)) } } func TestDiskFileReader_ReadLines_EmptySpec(t *testing.T) { reader := NewDiskFileReader() _, _, err := reader.ReadLines("", "") if err == nil { t.Error("expected error for empty include spec") } } func TestMockFileReader_ReadLines(t *testing.T) { files := map[string][]string{ "test.c65": {"LDA #$00", "STA $D020"}, "empty": {}, } reader := NewMockFileReader(files) lines, _, err := reader.ReadLines("test.c65", "") if err != nil { t.Fatalf("unexpected error: %v", err) } if len(lines) != 2 { t.Errorf("expected 2 lines, got %d", len(lines)) } _, _, err = reader.ReadLines("notfound", "") if err == nil { t.Error("expected error for missing file") } } func TestMockFileReader_LibraryInclude(t *testing.T) { files := map[string][]string{ "": {"LDA #$00", "STA $D020"}, } reader := NewMockFileReader(files) lines, _, err := reader.ReadLines("", "") if err != nil { t.Fatalf("unexpected error: %v", err) } if len(lines) != 2 { t.Errorf("expected 2 lines, got %d", len(lines)) } } func TestMockFileReader_NormalInclude(t *testing.T) { files := map[string][]string{ "test_app.c65": {"JMP $1000"}, } reader := NewMockFileReader(files) lines, _, err := reader.ReadLines("test_app.c65", "some/dir") if err != nil { t.Fatalf("unexpected error: %v", err) } if len(lines) != 1 { t.Errorf("expected 1 line, got %d", len(lines)) } } func TestMockFileReader_MissingFile(t *testing.T) { files := map[string][]string{ "exists.c65": {"NOP"}, } reader := NewMockFileReader(files) _, _, err := reader.ReadLines("notfound.c65", "") if err == nil { t.Error("expected error for missing file") } }