- Compiler: PP → Lexer → Parser → Analyzer → Gengo pipeline - Parser: 232/236 (98%) Harbour compatibility, registry-based dispatch - RTL: 351 Harbour-compatible functions - RDD: DBF/NTX/CDX engines with Rushmore bitmap optimization - Go Interop: IMPORT + pkg.Func() + obj:Method() with FastPath (15M calls/sec) - HB_FUNC API: Full Harbour C API compatible Go bridge - Concurrency: SPAWN/LAUNCH/GOROUTINE, <-, WATCH, PARALLEL FOR, ASYNC/AWAIT - Extensions: Multi-return, DEFER, Slice, f-string, Nil-safe ?:, CONST - Macro Compiler: Runtime AST parsing and evaluation - Debugger: TUI debugger with source display, breakpoints, stepping - FRB: Native + Pcode dual mode runtime binary - Tests: 13 packages ALL PASS Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
146 lines
3.1 KiB
Go
146 lines
3.1 KiB
Go
package hbrtl
|
|
|
|
import (
|
|
"os"
|
|
"runtime"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestGetEnv(t *testing.T) {
|
|
_, th := setupVM()
|
|
|
|
os.Setenv("FIVE_TEST_VAR", "hello123")
|
|
defer os.Unsetenv("FIVE_TEST_VAR")
|
|
|
|
th.PushString("FIVE_TEST_VAR")
|
|
th.PendingParams2(1)
|
|
GetEnv(th)
|
|
if r := th.GetRetValue().AsString(); r != "hello123" {
|
|
t.Errorf("GETENV('FIVE_TEST_VAR') = %q, want %q", r, "hello123")
|
|
}
|
|
|
|
// Non-existent
|
|
th.PushString("FIVE_NONEXISTENT_VAR_XYZ")
|
|
th.PendingParams2(1)
|
|
GetEnv(th)
|
|
if r := th.GetRetValue().AsString(); r != "" {
|
|
t.Errorf("GETENV(nonexistent) = %q, want empty", r)
|
|
}
|
|
|
|
// With default
|
|
th.PushString("FIVE_NONEXISTENT_VAR_XYZ")
|
|
th.PushString("default_val")
|
|
th.PendingParams2(2)
|
|
GetEnv(th)
|
|
if r := th.GetRetValue().AsString(); r != "default_val" {
|
|
t.Errorf("GETENV(nonexist, default) = %q, want %q", r, "default_val")
|
|
}
|
|
}
|
|
|
|
func TestOSFunc(t *testing.T) {
|
|
_, th := setupVM()
|
|
th.PendingParams2(0)
|
|
OSFunc(th)
|
|
r := th.GetRetValue().AsString()
|
|
if !strings.Contains(r, runtime.GOOS) {
|
|
t.Errorf("OS() = %q, should contain %q", r, runtime.GOOS)
|
|
}
|
|
}
|
|
|
|
func TestVersionFunc(t *testing.T) {
|
|
_, th := setupVM()
|
|
th.PendingParams2(0)
|
|
VersionFunc(th)
|
|
r := th.GetRetValue().AsString()
|
|
if !strings.HasPrefix(r, "Five") {
|
|
t.Errorf("VERSION() = %q, should start with 'Five'", r)
|
|
}
|
|
}
|
|
|
|
func TestHbFNameParts(t *testing.T) {
|
|
_, th := setupVM()
|
|
|
|
// Dir
|
|
th.PushString("/home/user/test.prg")
|
|
th.PendingParams2(1)
|
|
HbFNameDir(th)
|
|
r := th.GetRetValue().AsString()
|
|
if !strings.Contains(r, "home") {
|
|
t.Errorf("HB_FNAMEDIR = %q", r)
|
|
}
|
|
|
|
// Name
|
|
th.PushString("/home/user/test.prg")
|
|
th.PendingParams2(1)
|
|
HbFNameName(th)
|
|
if r := th.GetRetValue().AsString(); r != "test" {
|
|
t.Errorf("HB_FNAMENAME = %q, want 'test'", r)
|
|
}
|
|
|
|
// Ext
|
|
th.PushString("/home/user/test.prg")
|
|
th.PendingParams2(1)
|
|
HbFNameExt(th)
|
|
if r := th.GetRetValue().AsString(); r != ".prg" {
|
|
t.Errorf("HB_FNAMEEXT = %q, want '.prg'", r)
|
|
}
|
|
}
|
|
|
|
func TestCurDir(t *testing.T) {
|
|
_, th := setupVM()
|
|
th.PendingParams2(0)
|
|
CurDir(th)
|
|
r := th.GetRetValue().AsString()
|
|
if r == "" {
|
|
t.Error("CURDIR() returned empty")
|
|
}
|
|
}
|
|
|
|
func TestDirMakeRemove(t *testing.T) {
|
|
_, th := setupVM()
|
|
dir := t.TempDir()
|
|
newDir := dir + "/testsubdir"
|
|
|
|
// Make
|
|
th.PushString(newDir)
|
|
th.PendingParams2(1)
|
|
DirMake(th)
|
|
if r := th.GetRetValue().AsInt(); r != 0 {
|
|
t.Errorf("DIRMAKE = %d, want 0", r)
|
|
}
|
|
if fi, err := os.Stat(newDir); err != nil || !fi.IsDir() {
|
|
t.Error("Directory not created")
|
|
}
|
|
|
|
// Remove
|
|
th.PushString(newDir)
|
|
th.PendingParams2(1)
|
|
DirRemove(th)
|
|
if r := th.GetRetValue().AsInt(); r != 0 {
|
|
t.Errorf("DIRREMOVE = %d, want 0", r)
|
|
}
|
|
}
|
|
|
|
func TestDirectory(t *testing.T) {
|
|
_, th := setupVM()
|
|
dir := t.TempDir()
|
|
os.WriteFile(dir+"/a.txt", []byte("aaa"), 0644)
|
|
os.WriteFile(dir+"/b.txt", []byte("bb"), 0644)
|
|
os.WriteFile(dir+"/c.dat", []byte("c"), 0644)
|
|
|
|
// Match *.txt
|
|
th.PushString(dir + "/*.txt")
|
|
th.PendingParams2(1)
|
|
Directory(th)
|
|
arr := th.GetRetValue().AsArray()
|
|
if arr == nil || len(arr.Items) != 2 {
|
|
t.Errorf("DIRECTORY(*.txt) = %d items, want 2", func() int {
|
|
if arr == nil {
|
|
return 0
|
|
}
|
|
return len(arr.Items)
|
|
}())
|
|
}
|
|
}
|