dynamo-browse/internal/dynamo-browse/services/scriptmanager/service_test.go
Leon Mika f65c5778a9
issue-50: fixed package name (#52)
Changed package name from github.com/lmika/audax to github.com/lmika/dynamo-browse
2023-04-17 08:31:03 +10:00

151 lines
3.6 KiB
Go

package scriptmanager_test
import (
"context"
"github.com/lmika/dynamo-browse/internal/dynamo-browse/services/scriptmanager"
"github.com/lmika/dynamo-browse/internal/dynamo-browse/services/scriptmanager/mocks"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"io/fs"
"testing"
"testing/fstest"
"time"
)
func TestService_RunAdHocScript(t *testing.T) {
t.Run("successfully loads and executes a script", func(t *testing.T) {
testFS := testScriptFile(t, "test.tm", `
ui.print("Hello, world")
`)
mockedUIService := mocks.NewUIService(t)
mockedUIService.EXPECT().PrintMessage(mock.Anything, "Hello, world")
srv := scriptmanager.New(scriptmanager.WithFS(testFS))
srv.SetIFaces(scriptmanager.Ifaces{
UI: mockedUIService,
})
ctx := context.Background()
err := <-srv.RunAdHocScript(ctx, "test.tm")
assert.NoError(t, err)
mockedUIService.AssertExpectations(t)
})
}
func TestService_LoadScript(t *testing.T) {
t.Run("successfully loads a script and exposes it as a plugin", func(t *testing.T) {
testFS := testScriptFile(t, "test.tm", `
ext.command("somewhere", func(a) {
ui.print("Hello, " + a)
})
`)
ctx := context.Background()
mockedUIService := mocks.NewUIService(t)
mockedUIService.EXPECT().PrintMessage(mock.Anything, "Hello, someone")
srv := scriptmanager.New(scriptmanager.WithFS(testFS))
srv.SetIFaces(scriptmanager.Ifaces{
UI: mockedUIService,
})
plugin, err := srv.LoadScript(ctx, "test.tm")
assert.NoError(t, err)
assert.NotNil(t, plugin)
assert.Equal(t, "test", plugin.Name())
cmd := srv.LookupCommand("somewhere")
assert.NotNil(t, cmd)
errChan := make(chan error)
err = cmd.Invoke(ctx, []string{"someone"}, errChan)
assert.NoError(t, err)
assert.NoError(t, waitForErr(t, errChan))
mockedUIService.AssertExpectations(t)
})
t.Run("reloading a script with the same name should remove the old one", func(t *testing.T) {
testFS := fstest.MapFS{
"test.tm": &fstest.MapFile{
Data: []byte(`
ext.command("somewhere", func(a) {
ui.print("Hello, " + a)
})
`),
},
}
ctx := context.Background()
mockedUIService := mocks.NewUIService(t)
mockedUIService.EXPECT().PrintMessage(mock.Anything, "Hello, someone").Once()
mockedUIService.EXPECT().PrintMessage(mock.Anything, "Goodbye, someone").Once()
srv := scriptmanager.New(scriptmanager.WithFS(testFS))
srv.SetIFaces(scriptmanager.Ifaces{
UI: mockedUIService,
})
// Execute the old script
_, err := srv.LoadScript(ctx, "test.tm")
assert.NoError(t, err)
cmd := srv.LookupCommand("somewhere")
assert.NotNil(t, cmd)
errChan := make(chan error)
err = cmd.Invoke(ctx, []string{"someone"}, errChan)
assert.NoError(t, err)
assert.NoError(t, waitForErr(t, errChan))
// Change the script and reload
testFS["test.tm"] = &fstest.MapFile{
Data: []byte(`
ext.command("somewhere", func(a) {
ui.print("Goodbye, " + a)
})
`),
}
_, err = srv.LoadScript(ctx, "test.tm")
assert.NoError(t, err)
cmd = srv.LookupCommand("somewhere")
assert.NotNil(t, cmd)
errChan = make(chan error)
err = cmd.Invoke(ctx, []string{"someone"}, errChan)
assert.NoError(t, err)
assert.NoError(t, waitForErr(t, errChan))
mockedUIService.AssertExpectations(t)
})
}
func testScriptFile(t *testing.T, filename, code string) fs.FS {
t.Helper()
testFs := fstest.MapFS{
filename: &fstest.MapFile{
Data: []byte(code),
},
}
return testFs
}
func waitForErr(t *testing.T, errChan chan error) error {
t.Helper()
select {
case err := <-errChan:
return err
case <-time.After(5 * time.Second):
t.Fatalf("timed-out waiting for an error")
}
return nil
}