1package survey
2
3import (
4	"bytes"
5	"fmt"
6	"io"
7	"os"
8	"testing"
9
10	"github.com/AlecAivazis/survey/v2/core"
11	"github.com/AlecAivazis/survey/v2/terminal"
12	expect "github.com/Netflix/go-expect"
13	"github.com/stretchr/testify/assert"
14)
15
16func init() {
17	// disable color output for all prompts to simplify testing
18	core.DisableColor = true
19}
20
21func TestMultilineRender(t *testing.T) {
22
23	tests := []struct {
24		title    string
25		prompt   Multiline
26		data     MultilineTemplateData
27		expected string
28	}{
29		{
30			"Test Multiline question output without default",
31			Multiline{Message: "What is your favorite month:"},
32			MultilineTemplateData{},
33			fmt.Sprintf("%s What is your favorite month: [Enter 2 empty lines to finish]", defaultIcons().Question.Text),
34		},
35		{
36			"Test Multiline question output with default",
37			Multiline{Message: "What is your favorite month:", Default: "April"},
38			MultilineTemplateData{},
39			fmt.Sprintf("%s What is your favorite month: (April) [Enter 2 empty lines to finish]", defaultIcons().Question.Text),
40		},
41		{
42			"Test Multiline answer output",
43			Multiline{Message: "What is your favorite month:"},
44			MultilineTemplateData{Answer: "October", ShowAnswer: true},
45			fmt.Sprintf("%s What is your favorite month: \nOctober", defaultIcons().Question.Text),
46		},
47		{
48			"Test Multiline question output without default but with help hidden",
49			Multiline{Message: "What is your favorite month:", Help: "This is helpful"},
50			MultilineTemplateData{},
51			fmt.Sprintf("%s What is your favorite month: [Enter 2 empty lines to finish]", string(defaultPromptConfig().HelpInput)),
52		},
53		{
54			"Test Multiline question output with default and with help hidden",
55			Multiline{Message: "What is your favorite month:", Default: "April", Help: "This is helpful"},
56			MultilineTemplateData{},
57			fmt.Sprintf("%s What is your favorite month: (April) [Enter 2 empty lines to finish]", string(defaultPromptConfig().HelpInput)),
58		},
59		{
60			"Test Multiline question output without default but with help shown",
61			Multiline{Message: "What is your favorite month:", Help: "This is helpful"},
62			MultilineTemplateData{ShowHelp: true},
63			fmt.Sprintf("%s This is helpful\n%s What is your favorite month: [Enter 2 empty lines to finish]", defaultIcons().Help.Text, defaultIcons().Question.Text),
64		},
65		{
66			"Test Multiline question output with default and with help shown",
67			Multiline{Message: "What is your favorite month:", Default: "April", Help: "This is helpful"},
68			MultilineTemplateData{ShowHelp: true},
69			fmt.Sprintf("%s This is helpful\n%s What is your favorite month: (April) [Enter 2 empty lines to finish]", defaultIcons().Help.Text, defaultIcons().Question.Text),
70		},
71	}
72
73	for _, test := range tests {
74		r, w, err := os.Pipe()
75		assert.Nil(t, err, test.title)
76
77		test.prompt.WithStdio(terminal.Stdio{Out: w})
78		test.data.Multiline = test.prompt
79		// set the icon set
80		test.data.Config = defaultPromptConfig()
81
82		err = test.prompt.Render(
83			MultilineQuestionTemplate,
84			test.data,
85		)
86		assert.Nil(t, err, test.title)
87
88		w.Close()
89		var buf bytes.Buffer
90		io.Copy(&buf, r)
91
92		assert.Contains(t, buf.String(), test.expected, test.title)
93	}
94}
95
96func TestMultilinePrompt(t *testing.T) {
97	tests := []PromptTest{
98		{
99			"Test Multiline prompt interaction",
100			&Multiline{
101				Message: "What is your name?",
102			},
103			func(c *expect.Console) {
104				c.ExpectString("What is your name?")
105				c.SendLine("Larry Bird\nI guess...\nnot sure\n\n")
106				c.ExpectEOF()
107			},
108			"Larry Bird\nI guess...\nnot sure",
109		},
110		{
111			"Test Multiline prompt interaction with default",
112			&Multiline{
113				Message: "What is your name?",
114				Default: "Johnny Appleseed",
115			},
116			func(c *expect.Console) {
117				c.ExpectString("What is your name?")
118				c.SendLine("\n\n")
119				c.ExpectEOF()
120			},
121			"Johnny Appleseed",
122		},
123		{
124			"Test Multiline prompt interaction overriding default",
125			&Multiline{
126				Message: "What is your name?",
127				Default: "Johnny Appleseed",
128			},
129			func(c *expect.Console) {
130				c.ExpectString("What is your name?")
131				c.SendLine("Larry Bird\n\n")
132				c.ExpectEOF()
133			},
134			"Larry Bird",
135		},
136		{
137			"Test Multiline does not implement help interaction",
138			&Multiline{
139				Message: "What is your name?",
140				Help:    "It might be Satoshi Nakamoto",
141			},
142			func(c *expect.Console) {
143				c.ExpectString("What is your name?")
144				c.SendLine("?")
145				c.SendLine("Satoshi Nakamoto\n\n")
146				c.ExpectEOF()
147			},
148			"?\nSatoshi Nakamoto",
149		},
150	}
151
152	for _, test := range tests {
153		t.Run(test.name, func(t *testing.T) {
154			RunPromptTest(t, test)
155		})
156	}
157}
158