235 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			235 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package cmdpacks_test
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	tea "github.com/charmbracelet/bubbletea"
 | |
| 	bus "github.com/lmika/events"
 | |
| 	"github.com/stretchr/testify/assert"
 | |
| 	"lmika.dev/cmd/dynamo-browse/internal/common/ui/commandctrl"
 | |
| 	"lmika.dev/cmd/dynamo-browse/internal/common/ui/commandctrl/cmdpacks"
 | |
| 	"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/controllers"
 | |
| 	"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/providers/dynamo"
 | |
| 	"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/providers/inputhistorystore"
 | |
| 	"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/providers/settingstore"
 | |
| 	"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/providers/workspacestore"
 | |
| 	"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/services/inputhistory"
 | |
| 	"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/services/itemrenderer"
 | |
| 	"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/services/jobs"
 | |
| 	keybindings_service "lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/services/keybindings"
 | |
| 	"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/services/tables"
 | |
| 	"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/services/viewsnapshot"
 | |
| 	"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/ui/keybindings"
 | |
| 	"lmika.dev/cmd/dynamo-browse/test/testdynamo"
 | |
| 	"lmika.dev/cmd/dynamo-browse/test/testworkspace"
 | |
| 	"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 testPasteBoard struct {
 | |
| 	content string
 | |
| }
 | |
| 
 | |
| func (t *testPasteBoard) ReadText() (string, bool) {
 | |
| 	return t.content, true
 | |
| }
 | |
| 
 | |
| func (t *testPasteBoard) WriteText(bts []byte) error {
 | |
| 	t.content = string(bts)
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| type services struct {
 | |
| 	CommandController *commandctrl.CommandController
 | |
| 	SelItemIndex      int
 | |
| 
 | |
| 	State *controllers.State
 | |
| 
 | |
| 	settingStore *settingstore.SettingStore
 | |
| 	table        string
 | |
| 	pasteboard   *testPasteBoard
 | |
| 
 | |
| 	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)
 | |
| 
 | |
| 	testPB := &testPasteBoard{}
 | |
| 	s := &services{
 | |
| 		table:             "service-test-data",
 | |
| 		settingStore:      settingStore,
 | |
| 		testDataGenerator: normalTestData,
 | |
| 		pasteboard:        testPB,
 | |
| 	}
 | |
| 
 | |
| 	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,
 | |
| 		testPB,
 | |
| 		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, testPB)
 | |
| 
 | |
| 	keyBindingService := keybindings_service.NewService(keybindings.Default())
 | |
| 	keyBindingController := controllers.NewKeyBindingController(keyBindingService, nil)
 | |
| 
 | |
| 	commandController, _ := commandctrl.NewCommandController(inputHistoryService,
 | |
| 		cmdpacks.NewStandardCommands(
 | |
| 			service,
 | |
| 			state,
 | |
| 			readController,
 | |
| 			writeController,
 | |
| 			exportController,
 | |
| 			keyBindingController,
 | |
| 			testPB,
 | |
| 			settingsController,
 | |
| 		),
 | |
| 	)
 | |
| 
 | |
| 	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
 | |
| }
 |