From 75f085d0b22ec4110982fae2fe9728bc44a57f96 Mon Sep 17 00:00:00 2001 From: Tristan Cartledge Date: Tue, 3 Jun 2025 09:22:10 +1000 Subject: [PATCH 1/2] fix: add the ability to provide a random source --- engine.go | 11 ++++++++++- internal/vm/vm.go | 10 +++++++++- internal/vm/vm_test.go | 24 +++++++++++++++++++++++- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/engine.go b/engine.go index f1b89c9..86a1ffa 100644 --- a/engine.go +++ b/engine.go @@ -113,6 +113,13 @@ func WithDebug() Opt { } } +// WithRandSource sets the random source to use in the engine. +func WithRandSource(randSource func() float64) Opt { + return func(e *Engine) { + e.randSource = randSource + } +} + // Engine provides the templating engine. type Engine struct { searchLocations []string @@ -125,6 +132,8 @@ type Engine struct { tracer trace.Tracer + randSource vm.RandSource + vm *vm.VM } @@ -248,7 +257,7 @@ func (e *Engine) init(ctx context.Context, data any) (*vm.VM, error) { return nil, ErrAlreadyInitialized } - v, err := vm.New() + v, err := vm.New(e.randSource) if err != nil { return nil, fmt.Errorf("failed to create vm: %w", err) } diff --git a/internal/vm/vm.go b/internal/vm/vm.go index 136ecac..fe12d6c 100644 --- a/internal/vm/vm.go +++ b/internal/vm/vm.go @@ -50,6 +50,8 @@ type Options struct { // Option represents an option for running a script. type Option func(*Options) +type RandSource func() float64 + // WithStartingLineNumber sets the starting line number for the script. func WithStartingLineNumber(lineNumber int) Option { return func(o *Options) { @@ -63,7 +65,7 @@ type program struct { } // New creates a new VM. -func New() (*VM, error) { +func New(randSource RandSource) (*VM, error) { g := goja.New() _, err := g.RunString(underscore.JS) if err != nil { @@ -73,6 +75,12 @@ func New() (*VM, error) { new(require.Registry).Enable(g) console.Enable(g) + if randSource != nil { + g.SetRandSource(func() float64 { + return randSource() + }) + } + return &VM{Runtime: g, globalSourceMapCache: make(map[string]*sourcemap.Consumer)}, nil } diff --git a/internal/vm/vm_test.go b/internal/vm/vm_test.go index d3e41ab..d1819bf 100644 --- a/internal/vm/vm_test.go +++ b/internal/vm/vm_test.go @@ -9,8 +9,30 @@ import ( "github.com/stretchr/testify/require" ) +func TestVM_Run_Runtime_Success(t *testing.T) { + v, err := vm.New(nil) + require.NoError(t, err) + + typeScript := `console.log("hello world");` + + _, err = v.Run(context.Background(), "test", typeScript) + assert.NoError(t, err) +} + +func TestVM_Run_Runtime_WithRandSource_Success(t *testing.T) { + v, err := vm.New(func() float64 { + return 0 + }) + require.NoError(t, err) + + typeScript := `console.log("hello world");` + + _, err = v.Run(context.Background(), "test", typeScript) + assert.NoError(t, err) +} + func TestVM_Run_Runtime_Errors(t *testing.T) { - v, err := vm.New() + v, err := vm.New(nil) require.NoError(t, err) typeScript := `type Test = { From cc2f8d93b75fad80a634affe90bf862d3d9ab515 Mon Sep 17 00:00:00 2001 From: Tristan Cartledge Date: Tue, 3 Jun 2025 09:29:26 +1000 Subject: [PATCH 2/2] fix --- internal/vm/vm.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/vm/vm.go b/internal/vm/vm.go index fe12d6c..7f2f027 100644 --- a/internal/vm/vm.go +++ b/internal/vm/vm.go @@ -50,6 +50,7 @@ type Options struct { // Option represents an option for running a script. type Option func(*Options) +// RandSource is a function that returns a seeded float64 value. type RandSource func() float64 // WithStartingLineNumber sets the starting line number for the script.