2025-11-01 13:29:49 +09:00
|
|
|
package hawk_test
|
|
|
|
|
|
|
|
|
|
import "hawk"
|
|
|
|
|
import "fmt"
|
|
|
|
|
import "os"
|
|
|
|
|
import "runtime"
|
|
|
|
|
import "runtime/debug"
|
|
|
|
|
import "sync"
|
|
|
|
|
import "testing"
|
|
|
|
|
import "time"
|
|
|
|
|
|
|
|
|
|
func exit_with_error(msg string, err error) {
|
|
|
|
|
fmt.Printf("ERROR: %s - %s\n", msg, err.Error())
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-02 13:27:58 +09:00
|
|
|
func make_hawk(script string) (*hawk.Hawk, error) {
|
2025-11-01 13:29:49 +09:00
|
|
|
var h *hawk.Hawk
|
|
|
|
|
var err error
|
|
|
|
|
|
|
|
|
|
h, err = hawk.New()
|
|
|
|
|
if err != nil { return nil, err }
|
|
|
|
|
|
2025-11-02 13:27:58 +09:00
|
|
|
err = h.ParseText(script)
|
|
|
|
|
if err != nil {
|
|
|
|
|
h.Close()
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2025-11-01 13:29:49 +09:00
|
|
|
|
|
|
|
|
return h, nil
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-02 13:27:58 +09:00
|
|
|
func run_hawk(h *hawk.Hawk, id int, t *testing.T, wg *sync.WaitGroup) {
|
|
|
|
|
var rtx *hawk.Rtx
|
2025-11-01 13:29:49 +09:00
|
|
|
var v *hawk.Val
|
|
|
|
|
//var ret string
|
|
|
|
|
var ret []byte //float64
|
2025-11-02 13:27:58 +09:00
|
|
|
var i int
|
2025-11-01 13:29:49 +09:00
|
|
|
var err error
|
|
|
|
|
|
|
|
|
|
defer wg.Done()
|
|
|
|
|
|
2025-11-02 13:27:58 +09:00
|
|
|
rtx, err = h.NewRtx(fmt.Sprintf("%d", id))
|
2025-11-01 13:29:49 +09:00
|
|
|
if err != nil {
|
2025-11-02 13:27:58 +09:00
|
|
|
t.Errorf("failed to create rtx id[%d] - %s", id, err.Error())
|
|
|
|
|
return
|
2025-11-01 13:29:49 +09:00
|
|
|
}
|
|
|
|
|
|
2025-11-02 13:27:58 +09:00
|
|
|
v, err = rtx.Call("x",
|
|
|
|
|
hawk.Must(rtx.NewVal/*FromInt*/(id + 10)),
|
|
|
|
|
hawk.Must(rtx.NewVal([]byte{'A',66,67,68,69})),
|
|
|
|
|
hawk.Must(rtx.NewVal/*FromStr*/("this is cool")))
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Errorf("failed to invoke function 'x' for rtx id[%d] - %s", id, err.Error())
|
|
|
|
|
rtx.Close()
|
|
|
|
|
return
|
|
|
|
|
}
|
2025-11-01 13:29:49 +09:00
|
|
|
|
|
|
|
|
ret, err = v.ToByteArr()
|
|
|
|
|
if err != nil {
|
2025-11-02 13:27:58 +09:00
|
|
|
t.Errorf("failed to get return value for rtx id[%d] - %s", id, err.Error())
|
|
|
|
|
rtx.Close()
|
|
|
|
|
return
|
2025-11-01 13:29:49 +09:00
|
|
|
}
|
2025-11-02 13:27:58 +09:00
|
|
|
fmt.Printf("RET[%d] => [%v]\n", id, ret)
|
|
|
|
|
|
|
|
|
|
// check if ValCount() returns the right number of values created explicitly
|
|
|
|
|
i = rtx.ValCount()
|
|
|
|
|
if i != 3 { t.Errorf("the number of val objects for rtx id[%d] must be 3. but %d was returned", id, i) }
|
|
|
|
|
|
|
|
|
|
rtx.Close()
|
2025-11-01 13:29:49 +09:00
|
|
|
|
2025-11-02 13:27:58 +09:00
|
|
|
// it's safe to all ValCount() after Close() has been called.
|
|
|
|
|
i = rtx.ValCount()
|
|
|
|
|
if i != 0 { t.Errorf("the number of val objects for rtx id[%d] must be 0. but %d was returned", id, i) }
|
2025-11-01 13:29:49 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Test1(t *testing.T) {
|
|
|
|
|
var h *hawk.Hawk
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
|
var i int
|
|
|
|
|
var err error
|
|
|
|
|
|
|
|
|
|
debug.SetGCPercent(100) // enable normal GC
|
|
|
|
|
|
2025-11-02 13:27:58 +09:00
|
|
|
h, err = make_hawk(`function x(a1, a2, a3) {
|
|
|
|
|
for (i = 0; i < 10; i++) {
|
|
|
|
|
printf("hello, world [%d] [%s] [%s]\n", a1, a2, a3);
|
|
|
|
|
##if (i == 3) sys::sleep(1);
|
|
|
|
|
}
|
|
|
|
|
##return "welcome to the jungle 999";
|
|
|
|
|
return 1.9923;
|
|
|
|
|
}`)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Errorf("Failed to make hawk - %s", err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
2025-11-01 13:29:49 +09:00
|
|
|
|
|
|
|
|
for i = 0; i < 10; i++ {
|
|
|
|
|
wg.Add(1)
|
2025-11-02 13:27:58 +09:00
|
|
|
go run_hawk(h, i, t, &wg)
|
2025-11-01 13:29:49 +09:00
|
|
|
}
|
|
|
|
|
wg.Wait()
|
|
|
|
|
|
2025-11-02 13:27:58 +09:00
|
|
|
// when rtx objects are all closed, the counter must drop to 0
|
|
|
|
|
i = h.RtxCount()
|
|
|
|
|
if i != 0 { t.Errorf("the number of rtx objects must be 0. but %d was returned", i) }
|
|
|
|
|
|
2025-11-01 13:29:49 +09:00
|
|
|
h.Close()
|
|
|
|
|
|
2025-11-02 13:27:58 +09:00
|
|
|
h = nil
|
2025-11-01 13:29:49 +09:00
|
|
|
fmt.Printf ("== END of run ==\n")
|
|
|
|
|
runtime.GC()
|
|
|
|
|
runtime.Gosched()
|
|
|
|
|
time.Sleep(1000 * time.Millisecond) // give finalizer time to print
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-02 13:27:58 +09:00
|
|
|
func Test2(t *testing.T) {
|
|
|
|
|
var h *hawk.Hawk
|
|
|
|
|
var rtx *hawk.Rtx
|
|
|
|
|
var err error
|
|
|
|
|
|
|
|
|
|
debug.SetGCPercent(100) // enable normal GC
|
|
|
|
|
|
|
|
|
|
h, err = make_hawk(`function get_map(s) {
|
|
|
|
|
@local x
|
|
|
|
|
x["hello"] = s
|
|
|
|
|
x[99] = "donkey is running"
|
|
|
|
|
x["what"] = "rankey gankey"
|
|
|
|
|
x[1.239] = @b"nice value"
|
|
|
|
|
return x
|
|
|
|
|
}
|
|
|
|
|
function get_arr(s) {
|
|
|
|
|
@local x;
|
|
|
|
|
x = hawk::array(s, (s %% s), 10, 20.99);
|
|
|
|
|
for (i in x) print i, x[i];
|
|
|
|
|
return x;
|
|
|
|
|
}`)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Errorf("Failed to make hawk - %s", err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rtx, err = h.NewRtx("test2")
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Errorf("failed to create rtx - %s", err.Error())
|
|
|
|
|
} else {
|
|
|
|
|
var v *hawk.Val
|
|
|
|
|
|
|
|
|
|
v, err = rtx.Call("get_map", hawk.Must(rtx.NewValFromStr("hawk flies")))
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Errorf("failed to call get_map - %s", err.Error())
|
|
|
|
|
} else {
|
|
|
|
|
if v.Type() != hawk.VAL_MAP {
|
|
|
|
|
t.Errorf("the returned value must be %s. but it was %s", hawk.VAL_MAP.String(), v.Type().String())
|
|
|
|
|
} else {
|
|
|
|
|
var f *hawk.Val
|
|
|
|
|
|
|
|
|
|
f = hawk.Must(v.MapField("hello"))
|
|
|
|
|
if f.Type() != hawk.VAL_STR {
|
|
|
|
|
t.Errorf("the value at the hello field must be a string. but it was %s", f.Type().String())
|
|
|
|
|
} else {
|
|
|
|
|
var sv string
|
|
|
|
|
sv = hawk.Must(f.ToStr())
|
|
|
|
|
if sv != "hawk flies" {
|
|
|
|
|
t.Errorf("the value for the hello field must be 'hawk flies'. but it was %s", sv)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
f, err = v.MapField("HELLO")
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Errorf("the value at the HELLO field must not be found. but it was %s", f.Type().String())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
v, err = rtx.Call("get_arr", hawk.Must(rtx.NewValFromStr("hawk flies")))
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Errorf("failed to call get_arr - %s", err.Error())
|
|
|
|
|
} else {
|
|
|
|
|
if v.Type() != hawk.VAL_ARR {
|
|
|
|
|
t.Errorf("the returned value must be %s. but it was %s", hawk.VAL_ARR.String(), v.Type().String())
|
|
|
|
|
} else {
|
|
|
|
|
var sz int
|
|
|
|
|
var f *hawk.Val
|
|
|
|
|
|
|
|
|
|
sz = v.ArrayTally()
|
|
|
|
|
if sz != 4 {
|
|
|
|
|
t.Errorf("the returned value must have 4 elements. but it had %d elements", sz)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
f = hawk.Must(v.ArrayField(2))
|
|
|
|
|
if f.Type() != hawk.VAL_STR {
|
|
|
|
|
t.Errorf("the value at the hello field must be a string. but it was %s", f.Type().String())
|
|
|
|
|
} else {
|
|
|
|
|
var sv string
|
|
|
|
|
sv = hawk.Must(f.ToStr())
|
|
|
|
|
if sv != "hawk flieshawk flies" {
|
|
|
|
|
t.Errorf("the value for the hello field must be 'hawk flieshawk flies'. but it was %s", sv)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
h.Close()
|
|
|
|
|
|
|
|
|
|
runtime.GC()
|
|
|
|
|
runtime.Gosched()
|
|
|
|
|
time.Sleep(1000 * time.Millisecond) // give finalizer time to print
|
|
|
|
|
}
|
|
|
|
|
|