Ctrl K
ComunidadGuías…

cli/cliui/select_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package cliui_test

import (
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"

	"github.com/coder/coder/v2/cli/cliui"
	"github.com/coder/coder/v2/codersdk"
	"github.com/coder/serpent"
)

func TestSelect(t *testing.T) {
	t.Parallel()
	t.Run("Select", func(t *testing.T) {
		t.Parallel()
		msgChan := make(chan string)
		go func() {
			resp, err := newSelect(cliui.SelectOptions{
				Options: []string{"First", "Second"},
			})
			assert.NoError(t, err)
			msgChan <- resp
		}()
		require.Equal(t, "First", <-msgChan)
	})
}

func newSelect(opts cliui.SelectOptions) (string, error) {
	value := ""
	cmd := &serpent.Command{
		Handler: func(inv *serpent.Invocation) error {
			var err error
			value, err = cliui.Select(inv, opts)
			return err
		},
	}
	inv := cmd.Invoke()
	return value, inv.Run()
}

func TestRichSelect(t *testing.T) {
	t.Parallel()
	t.Run("RichSelect", func(t *testing.T) {
		t.Parallel()

		msgChan := make(chan string)
		go func() {
			resp, err := newRichSelect(cliui.RichSelectOptions{
				Options: []codersdk.TemplateVersionParameterOption{
					{Name: "A-Name", Value: "A-Value", Description: "A-Description."},
					{Name: "B-Name", Value: "B-Value", Description: "B-Description."},
				},
			})
			assert.NoError(t, err)
			msgChan <- resp
		}()
		require.Equal(t, "A-Value", <-msgChan)
	})
}

func newRichSelect(opts cliui.RichSelectOptions) (string, error) {
	value := ""
	cmd := &serpent.Command{
		Handler: func(inv *serpent.Invocation) error {
			richOption, err := cliui.RichSelect(inv, opts)
			if err == nil {
				value = richOption.Value
			}
			return err
		},
	}
	inv := cmd.Invoke()
	return value, inv.Run()
}

func TestRichMultiSelect(t *testing.T) {
	t.Parallel()

	tests := []struct {
		name        string
		options     []codersdk.TemplateVersionParameterOption
		defaults    []string
		allowCustom bool
		want        []string
	}{
		{
			name: "Predefined",
			options: []codersdk.TemplateVersionParameterOption{
				{Name: "AAA", Description: "This is AAA", Value: "aaa"},
				{Name: "BBB", Description: "This is BBB", Value: "bbb"},
				{Name: "CCC", Description: "This is CCC", Value: "ccc"},
			},
			defaults:    []string{"bbb", "ccc"},
			allowCustom: false,
			want:        []string{"bbb", "ccc"},
		},
		{
			name: "Custom",
			options: []codersdk.TemplateVersionParameterOption{
				{Name: "AAA", Description: "This is AAA", Value: "aaa"},
				{Name: "BBB", Description: "This is BBB", Value: "bbb"},
				{Name: "CCC", Description: "This is CCC", Value: "ccc"},
			},
			defaults:    []string{"aaa", "bbb"},
			allowCustom: true,
			want:        []string{"aaa", "bbb"},
		},
		{
			name: "NoOptionSelected",
			options: []codersdk.TemplateVersionParameterOption{
				{Name: "AAA", Description: "This is AAA", Value: "aaa"},
				{Name: "BBB", Description: "This is BBB", Value: "bbb"},
				{Name: "CCC", Description: "This is CCC", Value: "ccc"},
			},
			defaults:    []string{},
			allowCustom: false,
			want:        []string{},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			t.Parallel()

			var selectedItems []string
			var err error
			cmd := &serpent.Command{
				Handler: func(inv *serpent.Invocation) error {
					selectedItems, err = cliui.RichMultiSelect(inv, cliui.RichMultiSelectOptions{
						Options:           tt.options,
						Defaults:          tt.defaults,
						EnableCustomInput: tt.allowCustom,
					})
					return err
				},
			}

			doneChan := make(chan struct{})
			go func() {
				defer close(doneChan)
				err := cmd.Invoke().Run()
				assert.NoError(t, err)
			}()
			<-doneChan

			require.Equal(t, tt.want, selectedItems)
		})
	}
}

func TestMultiSelect(t *testing.T) {
	t.Parallel()

	tests := []struct {
		name        string
		items       []string
		allowCustom bool
		want        []string
	}{
		{
			name:        "MultiSelect",
			items:       []string{"aaa", "bbb", "ccc"},
			allowCustom: false,
			want:        []string{"aaa", "bbb", "ccc"},
		},
		{
			name:        "MultiSelectWithCustomInput",
			items:       []string{"Code", "Chairs", "Whale", "Diamond", "Carrot"},
			allowCustom: true,
			want:        []string{"Code", "Chairs", "Whale", "Diamond", "Carrot"},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			t.Parallel()

			msgChan := make(chan []string)

			go func() {
				resp, err := newMultiSelect(tt.items, tt.allowCustom)
				assert.NoError(t, err)
				msgChan <- resp
			}()

			require.Equal(t, tt.want, <-msgChan)
		})
	}
}

func newMultiSelect(items []string, custom bool) ([]string, error) {
	var values []string
	cmd := &serpent.Command{
		Handler: func(inv *serpent.Invocation) error {
			selectedItems, err := cliui.MultiSelect(inv, cliui.MultiSelectOptions{
				Options:           items,
				Defaults:          items,
				EnableCustomInput: custom,
			})
			if err == nil {
				values = selectedItems
			}
			return err
		},
	}
	inv := cmd.Invoke()
	return values, inv.Run()
}