package hbrtl import ( "os" "path/filepath" "testing" ) func TestFCreateWriteReadClose(t *testing.T) { _, th := setupVM() dir := t.TempDir() fpath := filepath.Join(dir, "test.bin") // FCREATE th.PushString(fpath) th.PendingParams2(1) FCreate(th) h := th.GetRetValue().AsInt() if h < 0 { t.Fatalf("FCREATE failed: handle=%d", h) } // FWRITE th.PushInt(h) th.PushString("Hello Five!") th.PendingParams2(2) FWrite(th) n := th.GetRetValue().AsInt() if n != 11 { t.Errorf("FWRITE wrote %d bytes, want 11", n) } // FCLOSE th.PushInt(h) th.PendingParams2(1) FClose(th) if !th.GetRetValue().AsBool() { t.Error("FCLOSE returned false") } // FOPEN read th.PushString(fpath) th.PushInt(0) // read-only th.PendingParams2(2) FOpen(th) h2 := th.GetRetValue().AsInt() if h2 < 0 { t.Fatalf("FOPEN failed: handle=%d", h2) } // FREAD th.PushInt(h2) th.PushNil() // buffer (not used in our impl) th.PushInt(11) th.PendingParams2(3) FRead(th) data := th.GetRetValue().AsString() if data != "Hello Five!" { t.Errorf("FREAD = %q, want %q", data, "Hello Five!") } // FCLOSE th.PushInt(h2) th.PendingParams2(1) FClose(th) } func TestFSeek(t *testing.T) { _, th := setupVM() dir := t.TempDir() fpath := filepath.Join(dir, "seek.bin") // Create and write os.WriteFile(fpath, []byte("0123456789"), 0644) th.PushString(fpath) th.PushInt(0) th.PendingParams2(2) FOpen(th) h := th.GetRetValue().AsInt() // Seek to offset 5 from start th.PushInt(h) th.PushLong(5) th.PushInt(0) // from start th.PendingParams2(3) FSeek(th) pos := th.GetRetValue().AsLong() if pos != 5 { t.Errorf("FSEEK pos = %d, want 5", pos) } // Read from offset 5 th.PushInt(h) th.PushNil() th.PushInt(5) th.PendingParams2(3) FRead(th) if r := th.GetRetValue().AsString(); r != "56789" { t.Errorf("FREAD after seek = %q, want %q", r, "56789") } th.PushInt(h) th.PendingParams2(1) FClose(th) } func TestFEraseRename(t *testing.T) { _, th := setupVM() dir := t.TempDir() fpath := filepath.Join(dir, "todel.txt") os.WriteFile(fpath, []byte("x"), 0644) // FRENAME newPath := filepath.Join(dir, "renamed.txt") th.PushString(fpath) th.PushString(newPath) th.PendingParams2(2) FRename(th) if r := th.GetRetValue().AsInt(); r != 0 { t.Errorf("FRENAME = %d, want 0", r) } if _, err := os.Stat(newPath); err != nil { t.Error("Renamed file not found") } // FERASE th.PushString(newPath) th.PendingParams2(1) FErase(th) if r := th.GetRetValue().AsInt(); r != 0 { t.Errorf("FERASE = %d, want 0", r) } if _, err := os.Stat(newPath); err == nil { t.Error("File still exists after FERASE") } } func TestFWritePartial(t *testing.T) { _, th := setupVM() dir := t.TempDir() fpath := filepath.Join(dir, "partial.bin") // Create th.PushString(fpath) th.PendingParams2(1) FCreate(th) h := th.GetRetValue().AsInt() // Write only 3 bytes of "Hello" th.PushInt(h) th.PushString("Hello") th.PushInt(3) th.PendingParams2(3) FWrite(th) n := th.GetRetValue().AsInt() if n != 3 { t.Errorf("Partial FWRITE = %d, want 3", n) } th.PushInt(h) th.PendingParams2(1) FClose(th) // Verify data, _ := os.ReadFile(fpath) if string(data) != "Hel" { t.Errorf("File content = %q, want %q", string(data), "Hel") } }