dynamo-browse/internal/dynamo-browse/controllers/scripts_test.go
Leon Mika 7ca0cf6982
Converted scripting language Tamarin to Risor (#55)
- Converted Tamarin script language to Risor
- Added a "find" and "merge" method to the result set script type.
- Added the ability to copy the table of results to the pasteboard by pressing C
- Added the -q flag, which will run a query and display the results as a CSV file on the command line
- Upgraded Go to 1.21 in Github actions
- Fix issue with missing limits
- Added the '-where' switch to the mark
- Added the 'marked' function to the query expression.
- Added a sampled time and count on the right-side of the mode line
- Added the 'M' key binding to toggle the marked items
- Started working on tab completion for 'sa' and 'da' commands
- Added count and sample time to the right-side of the mode line
- Added Ctrl+V to the prompt to paste the text of the pasteboard with all whitespace characters trimmed
- Fixed failing unit tests
2023-10-06 15:27:06 +11:00

193 lines
5.7 KiB
Go

package controllers_test
import (
"testing"
"time"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
"github.com/lmika/dynamo-browse/internal/common/ui/events"
"github.com/lmika/dynamo-browse/internal/dynamo-browse/controllers"
"github.com/stretchr/testify/assert"
)
func TestScriptController_RunScript(t *testing.T) {
t.Run("should execute scripts successfully", func(t *testing.T) {
srv := newService(t, serviceConfig{
scriptFS: testScriptFile(t, "test.tm", `
ui.print("Hello world")
`),
})
msg := srv.scriptController.RunScript("test.tm")
assert.Nil(t, msg)
srv.msgSender.waitForAtLeastOneMessages(t, 5*time.Second)
assert.Len(t, srv.msgSender.msgs, 1)
assert.Equal(t, events.StatusMsg("Hello world"), srv.msgSender.msgs[0])
})
t.Run("session.result_set", func(t *testing.T) {
t.Run("should return current result set if not-nil", func(t *testing.T) {
srv := newService(t, serviceConfig{
tableName: "alpha-table",
scriptFS: testScriptFile(t, "test.tm", `
rs := session.result_set()
ui.print(rs.length)
`),
})
invokeCommand(t, srv.readController.Init())
msg := srv.scriptController.RunScript("test.tm")
assert.Nil(t, msg)
srv.msgSender.waitForAtLeastOneMessages(t, 5*time.Second)
assert.Len(t, srv.msgSender.msgs, 1)
assert.Equal(t, events.StatusMsg("3"), srv.msgSender.msgs[0])
})
})
t.Run("session.query", func(t *testing.T) {
t.Run("should run query against current table", func(t *testing.T) {
srv := newService(t, serviceConfig{
tableName: "alpha-table",
scriptFS: testScriptFile(t, "test.tm", `
rs := session.query('pk="abc"')
ui.print(rs.length)
`),
})
invokeCommand(t, srv.readController.Init())
msg := srv.scriptController.RunScript("test.tm")
assert.Nil(t, msg)
srv.msgSender.waitForAtLeastOneMessages(t, 5*time.Second)
assert.Len(t, srv.msgSender.msgs, 1)
assert.Equal(t, events.StatusMsg("2"), srv.msgSender.msgs[0])
})
t.Run("should run query against another table", func(t *testing.T) {
srv := newService(t, serviceConfig{
tableName: "alpha-table",
scriptFS: testScriptFile(t, "test.tm", `
rs := session.query('pk!="abc"', { table: "count-to-30" })
ui.print(rs.length)
`),
})
invokeCommand(t, srv.readController.Init())
msg := srv.scriptController.RunScript("test.tm")
assert.Nil(t, msg)
srv.msgSender.waitForAtLeastOneMessages(t, 5*time.Second)
assert.Len(t, srv.msgSender.msgs, 1)
assert.Equal(t, events.StatusMsg("30"), srv.msgSender.msgs[0])
})
})
t.Run("session.set_result_set", func(t *testing.T) {
t.Run("should set the result set from the result of a query", func(t *testing.T) {
srv := newService(t, serviceConfig{
tableName: "alpha-table",
scriptFS: testScriptFile(t, "test.tm", `
rs := session.query('pk="abc"')
session.set_result_set(rs)
`),
})
invokeCommand(t, srv.readController.Init())
msg := srv.scriptController.RunScript("test.tm")
assert.Nil(t, msg)
srv.msgSender.waitForAtLeastOneMessages(t, 5*time.Second)
assert.Len(t, srv.msgSender.msgs, 1)
assert.IsType(t, controllers.NewResultSet{}, srv.msgSender.msgs[0])
})
t.Run("changed attributes of the result set should show up as modified", func(t *testing.T) {
srv := newService(t, serviceConfig{
tableName: "alpha-table",
scriptFS: testScriptFile(t, "test.tm", `
rs := session.query('pk="abc"')
rs[0].set_attr("pk", "131")
session.set_result_set(rs)
`),
})
invokeCommand(t, srv.readController.Init())
msg := srv.scriptController.RunScript("test.tm")
assert.Nil(t, msg)
srv.msgSender.waitForAtLeastOneMessages(t, 5*time.Second)
assert.Len(t, srv.msgSender.msgs, 1)
assert.IsType(t, controllers.NewResultSet{}, srv.msgSender.msgs[0])
assert.Equal(t, "131", srv.state.ResultSet().Items()[0]["pk"].(*types.AttributeValueMemberS).Value)
assert.True(t, srv.state.ResultSet().IsDirty(0))
})
})
}
func TestScriptController_LookupCommand(t *testing.T) {
t.Run("should schedule the script on a separate go-routine", func(t *testing.T) {
scenarios := []struct {
descr string
command string
expectedOutput string
}{
{descr: "command with arg", command: "mycommand \"test name\"", expectedOutput: "Hello, test name"},
{descr: "command no arg", command: "mycommand", expectedOutput: "Hello, nil value"},
}
for _, scenario := range scenarios {
t.Run(scenario.descr, func(t *testing.T) {
srv := newService(t, serviceConfig{
tableName: "alpha-table",
scriptFS: testScriptFile(t, "test.tm", `
ext.command("mycommand", func(name = "nil value") {
ui.print(sprintf("Hello, %v", name))
})
`),
})
invokeCommand(t, srv.scriptController.LoadScript("test.tm"))
invokeCommand(t, srv.commandController.Execute(scenario.command))
srv.msgSender.waitForAtLeastOneMessages(t, 5*time.Second)
assert.Len(t, srv.msgSender.msgs, 1)
assert.Equal(t, events.StatusMsg(scenario.expectedOutput), srv.msgSender.msgs[0])
})
}
})
t.Run("should only allow one script to run at a time", func(t *testing.T) {
srv := newService(t, serviceConfig{
tableName: "alpha-table",
scriptFS: testScriptFile(t, "test.tm", `
ext.command("mycommand", func() {
time.sleep(1.5)
ui.print("Done my thing")
})
`),
})
invokeCommand(t, srv.scriptController.LoadScript("test.tm"))
invokeCommand(t, srv.commandController.Execute(`mycommand`))
invokeCommandExpectingError(t, srv.commandController.Execute(`mycommand`))
srv.msgSender.waitForAtLeastOneMessages(t, 5*time.Second)
assert.Len(t, srv.msgSender.msgs, 1)
assert.Equal(t, events.StatusMsg("Done my thing"), srv.msgSender.msgs[0])
})
}