- 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>
117 lines
2.7 KiB
Go
117 lines
2.7 KiB
Go
package hbrtl
|
|
|
|
import (
|
|
"five/hbrt"
|
|
"testing"
|
|
)
|
|
|
|
func TestHbRegexMatch(t *testing.T) {
|
|
_, th := setupVM()
|
|
// Match
|
|
th.PushString("[0-9]+")
|
|
th.PushString("abc123def")
|
|
th.PendingParams2(2)
|
|
HbRegexMatch(th)
|
|
if !th.GetRetValue().AsBool() {
|
|
t.Error("HB_REGEXMATCH('[0-9]+', 'abc123def') = false, want true")
|
|
}
|
|
|
|
// No match
|
|
th.PushString("^[0-9]+$")
|
|
th.PushString("abc123def")
|
|
th.PendingParams2(2)
|
|
HbRegexMatch(th)
|
|
if th.GetRetValue().AsBool() {
|
|
t.Error("HB_REGEXMATCH('^[0-9]+$', 'abc123def') = true, want false")
|
|
}
|
|
}
|
|
|
|
func TestHbRegexSplit(t *testing.T) {
|
|
_, th := setupVM()
|
|
th.PushString("[,;]")
|
|
th.PushString("a,b;c,d")
|
|
th.PendingParams2(2)
|
|
HbRegexSplit(th)
|
|
arr := th.GetRetValue().AsArray()
|
|
if arr == nil || len(arr.Items) != 4 {
|
|
t.Fatalf("HB_REGEXSPLIT: expected 4 items, got %v", arr)
|
|
}
|
|
expected := []string{"a", "b", "c", "d"}
|
|
for i, exp := range expected {
|
|
if arr.Items[i].AsString() != exp {
|
|
t.Errorf("HB_REGEXSPLIT[%d] = %q, want %q", i, arr.Items[i].AsString(), exp)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestHbRegexAll(t *testing.T) {
|
|
_, th := setupVM()
|
|
th.PushString("[0-9]+")
|
|
th.PushString("a1b22c333")
|
|
th.PendingParams2(2)
|
|
HbRegexAll(th)
|
|
arr := th.GetRetValue().AsArray()
|
|
if arr == nil || len(arr.Items) != 3 {
|
|
t.Fatalf("HB_REGEXALL: expected 3 matches, got %v", arr)
|
|
}
|
|
expected := []string{"1", "22", "333"}
|
|
for i, exp := range expected {
|
|
if arr.Items[i].AsString() != exp {
|
|
t.Errorf("HB_REGEXALL[%d] = %q, want %q", i, arr.Items[i].AsString(), exp)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestHbRegexReplace(t *testing.T) {
|
|
_, th := setupVM()
|
|
th.PushString("[0-9]+")
|
|
th.PushString("a1b22c333")
|
|
th.PushString("X")
|
|
th.PendingParams2(3)
|
|
HbRegexReplace(th)
|
|
result := th.GetRetValue().AsString()
|
|
if result != "aXbXcX" {
|
|
t.Errorf("HB_REGEXREPLACE = %q, want %q", result, "aXbXcX")
|
|
}
|
|
}
|
|
|
|
func TestHbRegexComp(t *testing.T) {
|
|
_, th := setupVM()
|
|
// Compile
|
|
th.PushString("[a-z]+")
|
|
th.PendingParams2(1)
|
|
HbRegexComp(th)
|
|
compiled := th.GetRetValue()
|
|
if compiled.IsNil() {
|
|
t.Fatal("HB_REGEXCOMP returned NIL")
|
|
}
|
|
if !compiled.IsPointer() {
|
|
t.Fatal("HB_REGEXCOMP did not return pointer")
|
|
}
|
|
|
|
// Use compiled regex in match
|
|
th.PushValue(compiled)
|
|
th.PushString("HELLO123")
|
|
th.PendingParams2(2)
|
|
HbRegexMatch(th)
|
|
// Should not match — pattern is lowercase only, input is uppercase
|
|
if th.GetRetValue().AsBool() {
|
|
t.Error("Compiled [a-z]+ matched HELLO123, should not")
|
|
}
|
|
|
|
// Compile case-insensitive
|
|
th.PushString("[a-z]+")
|
|
th.PushValue(hbrt.MakeBool(false)) // case insensitive
|
|
th.PendingParams2(2)
|
|
HbRegexComp(th)
|
|
compiled2 := th.GetRetValue()
|
|
|
|
th.PushValue(compiled2)
|
|
th.PushString("HELLO123")
|
|
th.PendingParams2(2)
|
|
HbRegexMatch(th)
|
|
if !th.GetRetValue().AsBool() {
|
|
t.Error("Case-insensitive [a-z]+ should match HELLO123")
|
|
}
|
|
}
|