package runtime import ( "bytes" "context" "os" "strings" "testing" "github.com/fastschema/qjs" "github.com/stretchr/testify/assert" "reichard.io/poiesis/internal/functions" ) type TestArgs struct { Field1 string `json:"field1"` } func (t TestArgs) Validate() error { return nil } func TestExecuteTypeScript(t *testing.T) { var stdout, stderr bytes.Buffer rt, err := New(context.Background(), WithStderr(&stderr), WithStdout(&stdout)) assert.NoError(t, err, "Expected no error") tsCode := `interface Person { name: string; age: number; email: string; } function greet(person: Person): string { return "Hello, " + person.name + "! You are " + person.age + " years old."; } const user: Person = { name: "Alice", age: 30, email: "alice@example.com", }; console.log(greet(user)); console.log("Email: " + user.email); function calculateSum(a: number, b: number): number { return a + b; } console.log("Sum of 5 and 10 is: " + calculateSum(5, 10)); ` tmpFile, err := os.CreateTemp("", "*.ts") assert.NoError(t, err, "Failed to create temp file") t.Cleanup(func() { _ = os.Remove(tmpFile.Name()) }) _, err = tmpFile.WriteString(tsCode) assert.NoError(t, err, "Failed to write to temp file") err = tmpFile.Close() assert.NoError(t, err, "Failed to close temp file") err = rt.RunFile(tmpFile.Name()) assert.NoError(t, err, "Expected no error") assert.Empty(t, stderr.String(), "Expected no error output") output := stdout.String() assert.Contains(t, output, "Hello, Alice!", "Should greet Alice") assert.Contains(t, output, "You are 30 years old", "Should show age") assert.Contains(t, output, "Email: alice@example.com", "Should show email") assert.Contains(t, output, "Sum of 5 and 10 is: 15", "Should calculate sum correctly") lines := strings.Split(strings.TrimSpace(output), "\n") assert.GreaterOrEqual(t, len(lines), 3, "Should have at least 3 output lines") } func TestAsyncFunctionResolution(t *testing.T) { functions.RegisterAsyncFunction("resolveTest", func(_ context.Context, args TestArgs) (string, error) { return "test-result", nil }) r, err := New(context.Background()) assert.NoError(t, err) result, err := r.ctx.Eval("test.js", qjs.Code(`(async () => { return await resolveTest({field1: "hello"}); })()`)) if err == nil && result != nil { defer result.Free() val, err := result.Await() assert.NoError(t, err) assert.Equal(t, "test-result", val.String()) } else { t.Logf("Skipping async test - error: %v", err) } } func TestAsyncFunctionRejection(t *testing.T) { functions.RegisterAsyncFunction("rejectTest", func(_ context.Context, args TestArgs) (string, error) { return "", assert.AnError }) r, err := New(context.Background()) assert.NoError(t, err) _, err = r.ctx.Eval("test.js", qjs.Code(`(async () => { return await rejectTest({field1: "hello"}); })()`)) assert.Error(t, err) } func TestNonPromise(t *testing.T) { functions.RegisterFunction("nonPromiseTest", func(_ context.Context, args TestArgs) (string, error) { return "sync-result", nil }) r, err := New(context.Background()) assert.NoError(t, err) result, err := r.ctx.Eval("test.js", qjs.Code(`nonPromiseTest("hello")`)) assert.NoError(t, err) defer result.Free() assert.Equal(t, "sync-result", result.String()) }