package runtime import ( "bytes" "context" "os" "strings" "testing" "github.com/fastschema/qjs" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "reichard.io/poiesis/internal/functions" ) type TestArgs struct { Field1 string `json:"field1"` } func (t TestArgs) Validate() error { return nil } func TestExecuteTypeScript(t *testing.T) { // Create Buffers var stdout, stderr bytes.Buffer // Create Runtime rt, err := New(context.Background(), WithStderr(&stderr), WithStdout(&stdout)) assert.NoError(t, err, "Expected no error") // Create TypeScript Code 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)); ` // Create Temp File tmpFile, err := os.CreateTemp("", "*.ts") assert.NoError(t, err, "Failed to create temp file") t.Cleanup(func() { _ = os.Remove(tmpFile.Name()) }) // Write Code to File _, 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") // Run File err = rt.RunFile(tmpFile.Name()) // Verify Execution assert.NoError(t, err, "Expected no error") assert.Empty(t, stderr.String(), "Expected no error output") // Verify 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") // Verify Line Count 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) { // Register Async Function functions.RegisterAsyncFunction("resolveTest", func(_ context.Context, args TestArgs) (string, error) { return "test-result", nil }) // Create Runtime r, err := New(context.Background()) require.NoError(t, err) // Execute Async Function - Must be awaited in async context result, err := r.ctx.Eval("test.js", qjs.Code(`async function run() { return await resolveTest("hello"); }; run()`)) require.NoError(t, err) require.NotNil(t, result) defer result.Free() // Verify Result assert.Equal(t, "test-result", result.String()) } func TestAsyncFunctionRejection(t *testing.T) { // Register Async Function that Returns Error functions.RegisterAsyncFunction("rejectTest", func(_ context.Context, args TestArgs) (string, error) { return "", assert.AnError }) // Create Runtime r, err := New(context.Background()) require.NoError(t, err) // Execute Async Function - Rejected Promises Throw When Awaited _, err = r.ctx.Eval("test.js", qjs.Code(`async function run() { return await rejectTest("hello"); }; run()`)) assert.Error(t, err) } func TestNonPromise(t *testing.T) { // Register Sync Function functions.RegisterFunction("nonPromiseTest", func(_ context.Context, args TestArgs) (string, error) { return "sync-result", nil }) // Create Runtime r, err := New(context.Background()) assert.NoError(t, err) // Execute Sync Function result, err := r.ctx.Eval("test.js", qjs.Code(`nonPromiseTest("hello")`)) assert.NoError(t, err) defer result.Free() // Verify Result assert.Equal(t, "sync-result", result.String()) } func TestGetTypeDeclarations(t *testing.T) { // Register Function functions.RegisterFunction("testFunc", func(_ context.Context, args TestArgs) (string, error) { return "result", nil }) // Create Runtime r, err := New(context.Background()) require.NoError(t, err) // Get Type Declarations decls := r.GetTypeDeclarations() // Verify Declarations assert.Contains(t, decls, "interface TestArgs") assert.Contains(t, decls, "declare function testFunc") assert.Contains(t, decls, "field1: string") }