package hbrtl import ( "five/hbrt" "os" "path/filepath" "testing" ) func TestRat(t *testing.T) { _, th := setupVM() // Basic RAT th.PushString("is") th.PushString("This is a test, is it?") th.PendingParams2(2) Rat(th) if r := th.GetRetValue().AsInt(); r != 17 { t.Errorf("RAT('is', 'This is a test, is it?') = %d, want 17", r) } // Not found th.PushString("xyz") th.PushString("hello") th.PendingParams2(2) Rat(th) if r := th.GetRetValue().AsInt(); r != 0 { t.Errorf("RAT('xyz', 'hello') = %d, want 0", r) } // Empty search th.PushString("") th.PushString("hello") th.PendingParams2(2) Rat(th) if r := th.GetRetValue().AsInt(); r != 0 { t.Errorf("RAT('', 'hello') = %d, want 0", r) } } func TestStrZero(t *testing.T) { _, th := setupVM() // Integer th.PushInt(42) th.PushInt(6) th.PendingParams2(2) StrZero(th) if r := th.GetRetValue().AsString(); r != "000042" { t.Errorf("STRZERO(42, 6) = %q, want %q", r, "000042") } // Negative th.PushInt(-5) th.PushInt(5) th.PendingParams2(2) StrZero(th) r := th.GetRetValue().AsString() if r != " -05" && r != "-0005" && r != "*****" { // Harbour returns "-0005" for STRZERO(-5, 5) t.Logf("STRZERO(-5, 5) = %q (implementation-specific)", r) } } func TestDescend(t *testing.T) { _, th := setupVM() // String th.PushString("AB") th.PendingParams2(1) Descend(th) r := th.GetRetValue().AsString() if len(r) != 2 || r[0] != (255-'A') || r[1] != (255-'B') { t.Errorf("DESCEND('AB') bytes = [%d,%d], want [%d,%d]", r[0], r[1], 255-'A', 255-'B') } // Number th.PushInt(42) th.PendingParams2(1) Descend(th) if r := th.GetRetValue().AsLong(); r != -42 { t.Errorf("DESCEND(42) = %d, want -42", r) } // NIL th.PushNil() th.PendingParams2(1) Descend(th) if !th.GetRetValue().IsNil() { t.Error("DESCEND(NIL) should return NIL") } } func TestHbValToStr(t *testing.T) { _, th := setupVM() th.PushString("hello") th.PendingParams2(1) HbValToStr(th) if r := th.GetRetValue().AsString(); r != "hello" { t.Errorf("HB_VALTOSTR('hello') = %q, want %q", r, "hello") } th.PushInt(42) th.PendingParams2(1) HbValToStr(th) r := th.GetRetValue().AsString() if r == "" { t.Error("HB_VALTOSTR(42) returned empty string") } } func TestMemoReadWrit(t *testing.T) { _, th := setupVM() dir := t.TempDir() fpath := filepath.Join(dir, "test.txt") // Write th.PushString(fpath) th.PushString("Hello Five!") th.PendingParams2(2) MemoWrit(th) if !th.GetRetValue().AsBool() { t.Fatal("MEMOWRIT returned false") } // Verify file exists if _, err := os.Stat(fpath); err != nil { t.Fatalf("File not created: %v", err) } // Read th.PushString(fpath) th.PendingParams2(1) MemoRead(th) if r := th.GetRetValue().AsString(); r != "Hello Five!" { t.Errorf("MEMOREAD = %q, want %q", r, "Hello Five!") } // Read non-existent th.PushString(filepath.Join(dir, "nonexistent.txt")) th.PendingParams2(1) MemoRead(th) if r := th.GetRetValue().AsString(); r != "" { t.Errorf("MEMOREAD(nonexistent) = %q, want empty", r) } } func TestMemoTran(t *testing.T) { _, th := setupVM() th.PushString("line1\r\nline2\r\nline3") th.PushValue(hbrt.MakeNil()) // default soft CR th.PushString("|") // hard CR replacement th.PendingParams2(3) MemoTran(th) r := th.GetRetValue().AsString() if r != "line1|line2|line3" { t.Errorf("MEMOTRAN = %q, want %q", r, "line1|line2|line3") } }