package cmdpacks_test import ( "fmt" tea "github.com/charmbracelet/bubbletea" "github.com/lmika/dynamo-browse/internal/common/ui/commandctrl" "github.com/lmika/dynamo-browse/internal/common/ui/commandctrl/cmdpacks" "github.com/lmika/dynamo-browse/internal/dynamo-browse/controllers" "github.com/lmika/dynamo-browse/internal/dynamo-browse/providers/dynamo" "github.com/lmika/dynamo-browse/internal/dynamo-browse/providers/inputhistorystore" "github.com/lmika/dynamo-browse/internal/dynamo-browse/providers/pasteboardprovider" "github.com/lmika/dynamo-browse/internal/dynamo-browse/providers/settingstore" "github.com/lmika/dynamo-browse/internal/dynamo-browse/providers/workspacestore" "github.com/lmika/dynamo-browse/internal/dynamo-browse/services/inputhistory" "github.com/lmika/dynamo-browse/internal/dynamo-browse/services/itemrenderer" "github.com/lmika/dynamo-browse/internal/dynamo-browse/services/jobs" "github.com/lmika/dynamo-browse/internal/dynamo-browse/services/tables" "github.com/lmika/dynamo-browse/internal/dynamo-browse/services/viewsnapshot" "github.com/lmika/dynamo-browse/test/testdynamo" "github.com/lmika/dynamo-browse/test/testworkspace" bus "github.com/lmika/events" "github.com/stretchr/testify/assert" "testing" ) func TestStdCmds_Mark(t *testing.T) { tests := []struct { descr string cmd string wantMarks []bool }{ {descr: "mark default", cmd: "mark", wantMarks: []bool{true, true, true}}, {descr: "mark all", cmd: "mark all", wantMarks: []bool{true, true, true}}, {descr: "mark none", cmd: "mark none", wantMarks: []bool{false, false, false}}, {descr: "mark where", cmd: `mark -where 'sk="222"'`, wantMarks: []bool{false, true, false}}, {descr: "mark toggle", cmd: "mark ; mark toggle", wantMarks: []bool{false, false, false}}, } for _, tt := range tests { t.Run(tt.descr, func(t *testing.T) { svc := newService(t) _, err := svc.CommandController.ExecuteAndWait(t.Context(), tt.cmd) assert.NoError(t, err) for i, want := range tt.wantMarks { assert.Equal(t, want, svc.State.ResultSet().Marked(i)) } }) } } type testDataGenerator func() []testdynamo.TestData type services struct { CommandController *commandctrl.CommandController SelItemIndex int State *controllers.State settingStore *settingstore.SettingStore table string testDataGenerator testDataGenerator testData []testdynamo.TestData } type serviceOpt func(*services) func withDataGenerator(tg testDataGenerator) serviceOpt { return func(s *services) { s.testDataGenerator = tg } } func withTable(table string) serviceOpt { return func(s *services) { s.table = table } } func withDefaultLimit(limit int) serviceOpt { return func(s *services) { s.settingStore.SetDefaultLimit(limit) } } func newService(t *testing.T, opts ...serviceOpt) *services { ws := testworkspace.New(t) resultSetSnapshotStore := workspacestore.NewResultSetSnapshotStore(ws) settingStore := settingstore.New(ws) inputHistoryStore := inputhistorystore.NewInputHistoryStore(ws) workspaceService := viewsnapshot.NewService(resultSetSnapshotStore) itemRendererService := itemrenderer.NewService(itemrenderer.PlainTextRenderer(), itemrenderer.PlainTextRenderer()) inputHistoryService := inputhistory.New(inputHistoryStore) s := &services{ table: "service-test-data", settingStore: settingStore, testDataGenerator: normalTestData, } for _, opt := range opts { opt(s) } s.testData = s.testDataGenerator() client := testdynamo.SetupTestTable(t, s.testData) provider := dynamo.NewProvider(client) service := tables.NewService(provider, settingStore) eventBus := bus.New() state := controllers.NewState() jobsController := controllers.NewJobsController(jobs.NewService(eventBus), eventBus, true) readController := controllers.NewTableReadController( state, service, workspaceService, itemRendererService, jobsController, inputHistoryService, eventBus, pasteboardprovider.NilProvider{}, nil, s.table, ) writeController := controllers.NewTableWriteController(state, service, jobsController, readController, settingStore) settingsController := controllers.NewSettingsController(settingStore, eventBus) columnsController := controllers.NewColumnsController(readController, eventBus) exportController := controllers.NewExportController(state, service, jobsController, columnsController, pasteboardprovider.NilProvider{}) _ = settingsController commandController := commandctrl.NewCommandController(inputHistoryService, cmdpacks.StandardCommands{ State: state, TableService: service, ReadController: readController, WriteController: writeController, ExportController: exportController, }, ) s.State = state s.CommandController = commandController commandController.SetUIStateProvider(s) readController.Init() return s } func (s *services) SelectedItemIndex() int { return s.SelItemIndex } func (s *services) SetSelectedItemIndex(newIdx int) tea.Msg { s.SelItemIndex = newIdx return nil } func normalTestData() []testdynamo.TestData { return []testdynamo.TestData{ { TableName: "service-test-data", Data: []map[string]interface{}{ { "pk": "abc", "sk": "111", "alpha": "This is some value", }, { "pk": "abc", "sk": "222", "alpha": "This is another some value", "beta": 1231, }, { "pk": "bbb", "sk": "131", "beta": 2468, "gamma": "foobar", }, }, }, } } func largeTestData() []testdynamo.TestData { return []testdynamo.TestData{ { TableName: "large-table", Data: genRow(50, func(i int) map[string]interface{} { return map[string]interface{}{ "pk": fmt.Sprint(i), "sk": fmt.Sprint(i), "alpha": fmt.Sprintf("row %v", i), } }), }, } } func genRow(count int, mapFn func(int) map[string]interface{}) []map[string]interface{} { result := make([]map[string]interface{}, count) for i := 0; i < count; i++ { result[i] = mapFn(i) } return result }