From dbd0aee205a40de0e33405d0710d52857da6f9e5 Mon Sep 17 00:00:00 2001 From: RT Date: Sat, 8 Nov 2025 16:26:35 -0500 Subject: [PATCH] update go minimum ver to 1.25.4 --- .golangci.yml | 2 +- .../benchmark_2025-11-08_16-24-33.json | 45 ++++ .../results/benchmark_2025-11-08_16-24-33.txt | 13 + engines/benchmarks/results/comparison.txt | 55 +++-- engines/benchmarks/results/latest.txt | 2 +- go.mod | 2 +- readme_test.go | 222 ++++++++++++++++++ 7 files changed, 310 insertions(+), 31 deletions(-) create mode 100644 engines/benchmarks/results/benchmark_2025-11-08_16-24-33.json create mode 100644 engines/benchmarks/results/benchmark_2025-11-08_16-24-33.txt create mode 100644 readme_test.go diff --git a/.golangci.yml b/.golangci.yml index e8e4333..8934db7 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -2,7 +2,7 @@ version: '2' run: timeout: 5m - go: '1.24' + go: '1.25' linters: default: standard diff --git a/engines/benchmarks/results/benchmark_2025-11-08_16-24-33.json b/engines/benchmarks/results/benchmark_2025-11-08_16-24-33.json new file mode 100644 index 0000000..7bb6ee8 --- /dev/null +++ b/engines/benchmarks/results/benchmark_2025-11-08_16-24-33.json @@ -0,0 +1,45 @@ +{"Time":"2025-11-08T16:24:51.397504-05:00","Action":"start","Package":"github.com/robbyt/go-polyscript/engines/benchmarks"} +{"Time":"2025-11-08T16:24:51.412494-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Output":"goos: darwin\n"} +{"Time":"2025-11-08T16:24:51.412561-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Output":"goarch: amd64\n"} +{"Time":"2025-11-08T16:24:51.412571-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Output":"pkg: github.com/robbyt/go-polyscript/engines/benchmarks\n"} +{"Time":"2025-11-08T16:24:51.412584-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Output":"cpu: Intel(R) Xeon(R) W-3275M CPU @ 2.50GHz\n"} +{"Time":"2025-11-08T16:24:51.4126-05:00","Action":"run","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkEvaluationPatterns"} +{"Time":"2025-11-08T16:24:51.412607-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkEvaluationPatterns","Output":"=== RUN BenchmarkEvaluationPatterns\n"} +{"Time":"2025-11-08T16:24:51.412618-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkEvaluationPatterns","Output":"BenchmarkEvaluationPatterns\n"} +{"Time":"2025-11-08T16:24:51.412782-05:00","Action":"run","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkEvaluationPatterns/SingleExecution"} +{"Time":"2025-11-08T16:24:51.412815-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkEvaluationPatterns/SingleExecution","Output":"=== RUN BenchmarkEvaluationPatterns/SingleExecution\n"} +{"Time":"2025-11-08T16:24:51.412825-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkEvaluationPatterns/SingleExecution","Output":"BenchmarkEvaluationPatterns/SingleExecution\n"} +{"Time":"2025-11-08T16:24:53.498921-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkEvaluationPatterns/SingleExecution","Output":"BenchmarkEvaluationPatterns/SingleExecution-56 \t 5416\t 219009 ns/op\t 459874 B/op\t 1143 allocs/op\n"} +{"Time":"2025-11-08T16:24:53.499061-05:00","Action":"run","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkEvaluationPatterns/CompileOnceRunMany"} +{"Time":"2025-11-08T16:24:53.499078-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkEvaluationPatterns/CompileOnceRunMany","Output":"=== RUN BenchmarkEvaluationPatterns/CompileOnceRunMany\n"} +{"Time":"2025-11-08T16:24:53.499094-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkEvaluationPatterns/CompileOnceRunMany","Output":"BenchmarkEvaluationPatterns/CompileOnceRunMany\n"} +{"Time":"2025-11-08T16:24:54.563835-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkEvaluationPatterns/CompileOnceRunMany","Output":"BenchmarkEvaluationPatterns/CompileOnceRunMany-56 \t 8186\t 123443 ns/op\t 372585 B/op\t 449 allocs/op\n"} +{"Time":"2025-11-08T16:24:54.563935-05:00","Action":"run","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkDataProviders"} +{"Time":"2025-11-08T16:24:54.563953-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkDataProviders","Output":"=== RUN BenchmarkDataProviders\n"} +{"Time":"2025-11-08T16:24:54.56397-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkDataProviders","Output":"BenchmarkDataProviders\n"} +{"Time":"2025-11-08T16:24:54.59761-05:00","Action":"run","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkDataProviders/StaticProvider"} +{"Time":"2025-11-08T16:24:54.597676-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkDataProviders/StaticProvider","Output":"=== RUN BenchmarkDataProviders/StaticProvider\n"} +{"Time":"2025-11-08T16:24:54.597717-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkDataProviders/StaticProvider","Output":"BenchmarkDataProviders/StaticProvider\n"} +{"Time":"2025-11-08T16:24:55.832357-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkDataProviders/StaticProvider","Output":"BenchmarkDataProviders/StaticProvider-56 \t 9570\t 126490 ns/op\t 372488 B/op\t 449 allocs/op\n"} +{"Time":"2025-11-08T16:24:55.832452-05:00","Action":"run","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkDataProviders/ContextProvider"} +{"Time":"2025-11-08T16:24:55.832469-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkDataProviders/ContextProvider","Output":"=== RUN BenchmarkDataProviders/ContextProvider\n"} +{"Time":"2025-11-08T16:24:55.83248-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkDataProviders/ContextProvider","Output":"BenchmarkDataProviders/ContextProvider\n"} +{"Time":"2025-11-08T16:24:58.121832-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkDataProviders/ContextProvider","Output":"BenchmarkDataProviders/ContextProvider-56 \t 11998\t 114601 ns/op\t 371408 B/op\t 441 allocs/op\n"} +{"Time":"2025-11-08T16:24:58.121909-05:00","Action":"run","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkDataProviders/CompositeProvider"} +{"Time":"2025-11-08T16:24:58.121925-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkDataProviders/CompositeProvider","Output":"=== RUN BenchmarkDataProviders/CompositeProvider\n"} +{"Time":"2025-11-08T16:24:58.121936-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkDataProviders/CompositeProvider","Output":"BenchmarkDataProviders/CompositeProvider\n"} +{"Time":"2025-11-08T16:25:00.63048-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkDataProviders/CompositeProvider","Output":"BenchmarkDataProviders/CompositeProvider-56 \t 12882\t 128400 ns/op\t 372493 B/op\t 451 allocs/op\n"} +{"Time":"2025-11-08T16:25:00.630566-05:00","Action":"run","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkEngineComparison"} +{"Time":"2025-11-08T16:25:00.630593-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkEngineComparison","Output":"=== RUN BenchmarkEngineComparison\n"} +{"Time":"2025-11-08T16:25:00.630615-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkEngineComparison","Output":"BenchmarkEngineComparison\n"} +{"Time":"2025-11-08T16:25:00.683376-05:00","Action":"run","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkEngineComparison/RisorEngine"} +{"Time":"2025-11-08T16:25:00.683415-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkEngineComparison/RisorEngine","Output":"=== RUN BenchmarkEngineComparison/RisorEngine\n"} +{"Time":"2025-11-08T16:25:00.683426-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkEngineComparison/RisorEngine","Output":"BenchmarkEngineComparison/RisorEngine\n"} +{"Time":"2025-11-08T16:25:02.919157-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkEngineComparison/RisorEngine","Output":"BenchmarkEngineComparison/RisorEngine-56 \t 12753\t 116162 ns/op\t 372412 B/op\t 448 allocs/op\n"} +{"Time":"2025-11-08T16:25:02.919233-05:00","Action":"run","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkEngineComparison/StarlarkEngine"} +{"Time":"2025-11-08T16:25:02.919272-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkEngineComparison/StarlarkEngine","Output":"=== RUN BenchmarkEngineComparison/StarlarkEngine\n"} +{"Time":"2025-11-08T16:25:02.919288-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkEngineComparison/StarlarkEngine","Output":"BenchmarkEngineComparison/StarlarkEngine\n"} +{"Time":"2025-11-08T16:25:04.429874-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Test":"BenchmarkEngineComparison/StarlarkEngine","Output":"BenchmarkEngineComparison/StarlarkEngine-56 \t 129715\t 9981 ns/op\t 7798 B/op\t 71 allocs/op\n"} +{"Time":"2025-11-08T16:25:04.430255-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Output":"PASS\n"} +{"Time":"2025-11-08T16:25:04.685318-05:00","Action":"output","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Output":"ok \tgithub.com/robbyt/go-polyscript/engines/benchmarks\t13.288s\n"} +{"Time":"2025-11-08T16:25:04.685363-05:00","Action":"pass","Package":"github.com/robbyt/go-polyscript/engines/benchmarks","Elapsed":13.288} diff --git a/engines/benchmarks/results/benchmark_2025-11-08_16-24-33.txt b/engines/benchmarks/results/benchmark_2025-11-08_16-24-33.txt new file mode 100644 index 0000000..b6bcd85 --- /dev/null +++ b/engines/benchmarks/results/benchmark_2025-11-08_16-24-33.txt @@ -0,0 +1,13 @@ +goos: darwin +goarch: amd64 +pkg: github.com/robbyt/go-polyscript/engines/benchmarks +cpu: Intel(R) Xeon(R) W-3275M CPU @ 2.50GHz +BenchmarkEvaluationPatterns/SingleExecution-56 5330 210237 ns/op 459873 B/op 1143 allocs/op +BenchmarkEvaluationPatterns/CompileOnceRunMany-56 10648 126322 ns/op 372517 B/op 449 allocs/op +BenchmarkDataProviders/StaticProvider-56 12279 124480 ns/op 372475 B/op 449 allocs/op +BenchmarkDataProviders/ContextProvider-56 12877 118788 ns/op 371338 B/op 440 allocs/op +BenchmarkDataProviders/CompositeProvider-56 12510 111537 ns/op 372442 B/op 450 allocs/op +BenchmarkEngineComparison/RisorEngine-56 12565 111180 ns/op 372409 B/op 448 allocs/op +BenchmarkEngineComparison/StarlarkEngine-56 132204 10134 ns/op 7800 B/op 71 allocs/op +PASS +ok github.com/robbyt/go-polyscript/engines/benchmarks 15.327s diff --git a/engines/benchmarks/results/comparison.txt b/engines/benchmarks/results/comparison.txt index d06c27f..2c86cb5 100644 --- a/engines/benchmarks/results/comparison.txt +++ b/engines/benchmarks/results/comparison.txt @@ -2,42 +2,41 @@ goos: darwin goarch: amd64 pkg: github.com/robbyt/go-polyscript/engines/benchmarks cpu: Intel(R) Xeon(R) W-3275M CPU @ 2.50GHz - │ previous │ current │ - │ sec/op │ sec/op vs base │ -EvaluationPatterns/SingleExecution-56 273.5µ ± ∞ ¹ 284.7µ ± ∞ ¹ ~ (p=1.000 n=1) ² -EvaluationPatterns/CompileOnceRunMany-56 172.6µ ± ∞ ¹ 176.1µ ± ∞ ¹ ~ (p=1.000 n=1) ² -DataProviders/StaticProvider-56 176.8µ ± ∞ ¹ 180.6µ ± ∞ ¹ ~ (p=1.000 n=1) ² -DataProviders/ContextProvider-56 172.6µ ± ∞ ¹ 178.5µ ± ∞ ¹ ~ (p=1.000 n=1) ² -DataProviders/CompositeProvider-56 178.8µ ± ∞ ¹ 177.7µ ± ∞ ¹ ~ (p=1.000 n=1) ² -VMComparison/RisorEngine-56 171.0µ ± ∞ ¹ 183.4µ ± ∞ ¹ ~ (p=1.000 n=1) ² -VMComparison/StarlarkEngine-56 11.85µ ± ∞ ¹ 12.49µ ± ∞ ¹ ~ (p=1.000 n=1) ² -geomean 126.6µ 130.9µ +3.37% + │ previous │ current │ + │ sec/op │ sec/op vs base │ +EvaluationPatterns/SingleExecution-56 284.7µ ± ∞ ¹ 210.2µ ± ∞ ¹ ~ (p=1.000 n=1) ² +EvaluationPatterns/CompileOnceRunMany-56 176.1µ ± ∞ ¹ 126.3µ ± ∞ ¹ ~ (p=1.000 n=1) ² +DataProviders/StaticProvider-56 180.6µ ± ∞ ¹ 124.5µ ± ∞ ¹ ~ (p=1.000 n=1) ² +DataProviders/ContextProvider-56 178.5µ ± ∞ ¹ 118.8µ ± ∞ ¹ ~ (p=1.000 n=1) ² +DataProviders/CompositeProvider-56 177.7µ ± ∞ ¹ 111.5µ ± ∞ ¹ ~ (p=1.000 n=1) ² +EngineComparison/RisorEngine-56 183.4µ ± ∞ ¹ 111.2µ ± ∞ ¹ ~ (p=1.000 n=1) ² +EngineComparison/StarlarkEngine-56 12.49µ ± ∞ ¹ 10.13µ ± ∞ ¹ ~ (p=1.000 n=1) ² +geomean 130.9µ 90.40µ -30.93% ¹ need >= 6 samples for confidence interval at level 0.95 ² need >= 4 samples to detect a difference at alpha level 0.05 │ previous │ current │ │ B/op │ B/op vs base │ -EvaluationPatterns/SingleExecution-56 450.3Ki ± ∞ ¹ 450.3Ki ± ∞ ¹ ~ (p=1.000 n=1) ² -EvaluationPatterns/CompileOnceRunMany-56 365.0Ki ± ∞ ¹ 365.1Ki ± ∞ ¹ ~ (p=1.000 n=1) ² -DataProviders/StaticProvider-56 365.1Ki ± ∞ ¹ 365.1Ki ± ∞ ¹ ~ (p=1.000 n=1) ² -DataProviders/ContextProvider-56 364.0Ki ± ∞ ¹ 364.0Ki ± ∞ ¹ ~ (p=1.000 n=1) ² -DataProviders/CompositeProvider-56 365.6Ki ± ∞ ¹ 365.1Ki ± ∞ ¹ ~ (p=1.000 n=1) ² -VMComparison/RisorEngine-56 365.1Ki ± ∞ ¹ 365.1Ki ± ∞ ¹ ~ (p=1.000 n=1) ² -VMComparison/StarlarkEngine-56 7.596Ki ± ∞ ¹ 7.591Ki ± ∞ ¹ ~ (p=1.000 n=1) ² -geomean 216.3Ki 216.2Ki -0.02% +EvaluationPatterns/SingleExecution-56 450.3Ki ± ∞ ¹ 449.1Ki ± ∞ ¹ ~ (p=1.000 n=1) ² +EvaluationPatterns/CompileOnceRunMany-56 365.1Ki ± ∞ ¹ 363.8Ki ± ∞ ¹ ~ (p=1.000 n=1) ² +DataProviders/StaticProvider-56 365.1Ki ± ∞ ¹ 363.7Ki ± ∞ ¹ ~ (p=1.000 n=1) ² +DataProviders/ContextProvider-56 364.0Ki ± ∞ ¹ 362.6Ki ± ∞ ¹ ~ (p=1.000 n=1) ² +DataProviders/CompositeProvider-56 365.1Ki ± ∞ ¹ 363.7Ki ± ∞ ¹ ~ (p=1.000 n=1) ² +EngineComparison/RisorEngine-56 365.1Ki ± ∞ ¹ 363.7Ki ± ∞ ¹ ~ (p=1.000 n=1) ² +EngineComparison/StarlarkEngine-56 7.591Ki ± ∞ ¹ 7.617Ki ± ∞ ¹ ~ (p=1.000 n=1) ² +geomean 216.2Ki 215.7Ki -0.25% ¹ need >= 6 samples for confidence interval at level 0.95 ² need >= 4 samples to detect a difference at alpha level 0.05 │ previous │ current │ │ allocs/op │ allocs/op vs base │ -EvaluationPatterns/SingleExecution-56 1.164k ± ∞ ¹ 1.164k ± ∞ ¹ ~ (p=1.000 n=1) ² -EvaluationPatterns/CompileOnceRunMany-56 439.0 ± ∞ ¹ 439.0 ± ∞ ¹ ~ (p=1.000 n=1) ² -DataProviders/StaticProvider-56 439.0 ± ∞ ¹ 439.0 ± ∞ ¹ ~ (p=1.000 n=1) ² -DataProviders/ContextProvider-56 431.0 ± ∞ ¹ 431.0 ± ∞ ¹ ~ (p=1.000 n=1) ² -DataProviders/CompositeProvider-56 448.0 ± ∞ ¹ 441.0 ± ∞ ¹ ~ (p=1.000 n=1) ³ -VMComparison/RisorEngine-56 439.0 ± ∞ ¹ 439.0 ± ∞ ¹ ~ (p=1.000 n=1) ² -VMComparison/StarlarkEngine-56 72.00 ± ∞ ¹ 72.00 ± ∞ ¹ ~ (p=1.000 n=1) ² -geomean 389.9 389.0 -0.22% +EvaluationPatterns/SingleExecution-56 1.164k ± ∞ ¹ 1.143k ± ∞ ¹ ~ (p=1.000 n=1) ² +EvaluationPatterns/CompileOnceRunMany-56 439.0 ± ∞ ¹ 449.0 ± ∞ ¹ ~ (p=1.000 n=1) ² +DataProviders/StaticProvider-56 439.0 ± ∞ ¹ 449.0 ± ∞ ¹ ~ (p=1.000 n=1) ² +DataProviders/ContextProvider-56 431.0 ± ∞ ¹ 440.0 ± ∞ ¹ ~ (p=1.000 n=1) ² +DataProviders/CompositeProvider-56 441.0 ± ∞ ¹ 450.0 ± ∞ ¹ ~ (p=1.000 n=1) ² +EngineComparison/RisorEngine-56 439.0 ± ∞ ¹ 448.0 ± ∞ ¹ ~ (p=1.000 n=1) ² +EngineComparison/StarlarkEngine-56 72.00 ± ∞ ¹ 71.00 ± ∞ ¹ ~ (p=1.000 n=1) ² +geomean 389.0 393.1 +1.06% ¹ need >= 6 samples for confidence interval at level 0.95 -² all samples are equal -³ need >= 4 samples to detect a difference at alpha level 0.05 +² need >= 4 samples to detect a difference at alpha level 0.05 diff --git a/engines/benchmarks/results/latest.txt b/engines/benchmarks/results/latest.txt index e4d5f06..4eb2274 120000 --- a/engines/benchmarks/results/latest.txt +++ b/engines/benchmarks/results/latest.txt @@ -1 +1 @@ -benchmark_2025-04-14_22-42-30.txt \ No newline at end of file +benchmark_2025-11-08_16-24-33.txt \ No newline at end of file diff --git a/go.mod b/go.mod index 7064f2e..beec593 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/robbyt/go-polyscript -go 1.25.3 +go 1.25.4 require ( github.com/extism/go-sdk v1.7.1 diff --git a/readme_test.go b/readme_test.go new file mode 100644 index 0000000..2226af6 --- /dev/null +++ b/readme_test.go @@ -0,0 +1,222 @@ +package polyscript_test + +import ( + "context" + "log/slog" + "os" + "testing" + + "github.com/robbyt/go-polyscript" + "github.com/robbyt/go-polyscript/engines/extism/wasmdata" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestReadmeQuickStart(t *testing.T) { + t.Parallel() + + logger := slog.New(slog.NewTextHandler(os.Stdout, nil)) + + script := ` + // The ctx object from the Go inputData map + name := ctx.get("name") + + p := "." + if ctx.get("excited") { + p = "!" + } + + message := "Hello, " + name + p + + // Return a map with our result + { + "greeting": message, + "length": len(message) + } + ` + + inputData := map[string]any{"name": "World"} + + evaluator, err := polyscript.FromRisorStringWithData( + script, + inputData, + logger.Handler(), + ) + require.NoError(t, err, "Should create evaluator successfully") + + ctx := context.Background() + result, err := evaluator.Eval(ctx) + require.NoError(t, err, "Should evaluate successfully") + require.NotNil(t, result, "Result should not be nil") + + resultMap, ok := result.Interface().(map[string]any) + require.True(t, ok, "Result should be a map") + assert.Equal(t, "Hello, World.", resultMap["greeting"], "Greeting should match") + assert.Equal(t, int64(13), resultMap["length"], "Length should be 13") +} + +func TestReadmeStaticProvider(t *testing.T) { + t.Parallel() + + logger := slog.New(slog.NewTextHandler(os.Stdout, nil)) + + script := ` + name := ctx.get("name") + excited := ctx.get("excited") + + p := "." + if excited { + p = "!" + } + + message := "Hello, " + name + p + + { + "greeting": message + } + ` + + inputData := map[string]any{"name": "cats", "excited": true} + evaluator, err := polyscript.FromRisorStringWithData(script, inputData, logger.Handler()) + require.NoError(t, err, "Should create evaluator successfully") + + ctx := context.Background() + result, err := evaluator.Eval(ctx) + require.NoError(t, err, "Should evaluate successfully") + + resultMap, ok := result.Interface().(map[string]any) + require.True(t, ok, "Result should be a map") + assert.Equal(t, "Hello, cats!", resultMap["greeting"], "Greeting should match with excitement") +} + +func TestReadmeContextProvider(t *testing.T) { + t.Parallel() + + logger := slog.New(slog.NewTextHandler(os.Stdout, nil)) + + script := ` + name := ctx.get("name") + relationship := ctx.get("relationship") + + { + "name": name, + "is_not_my_lover": relationship == false + } + ` + + evaluator, err := polyscript.FromRisorString(script, logger.Handler()) + require.NoError(t, err, "Should create evaluator successfully") + + ctx := context.Background() + runtimeData := map[string]any{"name": "Billie Jean", "relationship": false} + enrichedCtx, err := evaluator.AddDataToContext(ctx, runtimeData) + require.NoError(t, err, "Should add data to context successfully") + + result, err := evaluator.Eval(enrichedCtx) + require.NoError(t, err, "Should evaluate successfully") + + resultMap, ok := result.Interface().(map[string]any) + require.True(t, ok, "Result should be a map") + assert.Equal(t, "Billie Jean", resultMap["name"], "Name should match") + assert.Equal(t, true, resultMap["is_not_my_lover"], "Relationship status should be correct") +} + +func TestReadmeCombiningStaticAndDynamic(t *testing.T) { + t.Parallel() + + logger := slog.New(slog.NewTextHandler(os.Stdout, nil)) + + script := ` + // Access both static and dynamic data + name := ctx.get("name") + excited := ctx.get("excited") + + p := "." + if excited { + p = "!" + } + + message := "Hello, " + name + p + + { + "greeting": message + } + ` + + staticData := map[string]any{ + "name": "User", + "excited": true, + } + + evaluator, err := polyscript.FromRisorStringWithData(script, staticData, logger.Handler()) + require.NoError(t, err, "Should create evaluator with static data") + + requestData := map[string]any{"name": "Robert"} + enrichedCtx, err := evaluator.AddDataToContext(context.Background(), requestData) + require.NoError(t, err, "Should add runtime data to context") + + result, err := evaluator.Eval(enrichedCtx) + require.NoError(t, err, "Should evaluate with combined data") + + resultMap, ok := result.Interface().(map[string]any) + require.True(t, ok, "Result should be a map") + assert.Equal(t, "Hello, Robert!", resultMap["greeting"], "Should use runtime name over static") +} + +func TestReadmeStarlark(t *testing.T) { + t.Parallel() + + logger := slog.New(slog.NewTextHandler(os.Stdout, nil)) + + scriptContent := ` +# Starlark has access to ctx variable +name = ctx["name"] +message = "Hello, " + name + "!" + +# Create the result dictionary +result = {"greeting": message, "length": len(message)} + +# Assign to _ to return the value +_ = result +` + + staticData := map[string]any{"name": "World"} + evaluator, err := polyscript.FromStarlarkStringWithData( + scriptContent, + staticData, + logger.Handler(), + ) + require.NoError(t, err, "Should create Starlark evaluator") + + result, err := evaluator.Eval(context.Background()) + require.NoError(t, err, "Should evaluate Starlark script") + + resultMap, ok := result.Interface().(map[string]any) + require.True(t, ok, "Result should be a map") + assert.Equal(t, "Hello, World!", resultMap["greeting"], "Greeting should match") + assert.Equal(t, int64(13), resultMap["length"], "Length should be 13") +} + +func TestReadmeExtism(t *testing.T) { + t.Parallel() + + logger := slog.New(slog.NewTextHandler(os.Stdout, nil)) + + staticData := map[string]any{"input": "World"} + evaluator, err := polyscript.FromExtismBytesWithData( + wasmdata.TestModule, + staticData, + logger.Handler(), + wasmdata.EntrypointGreet, + ) + require.NoError(t, err, "Should create Extism evaluator") + + result, err := evaluator.Eval(context.Background()) + require.NoError(t, err, "Should evaluate WASM module") + require.NotNil(t, result, "Result should not be nil") + + resultMap, ok := result.Interface().(map[string]any) + require.True(t, ok, "Result should be a map") + assert.Contains(t, resultMap, "greeting", "Result should contain greeting field") + assert.Equal(t, "Hello, World!", resultMap["greeting"], "Greeting should match") +}