1// Copyright 2011 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package terminal
6
7import (
8	"io"
9	"testing"
10)
11
12type MockTerminal struct {
13	toSend       []byte
14	bytesPerRead int
15	received     []byte
16}
17
18func (c *MockTerminal) Read(data []byte) (n int, err error) {
19	n = len(data)
20	if n == 0 {
21		return
22	}
23	if n > len(c.toSend) {
24		n = len(c.toSend)
25	}
26	if n == 0 {
27		return 0, io.EOF
28	}
29	if c.bytesPerRead > 0 && n > c.bytesPerRead {
30		n = c.bytesPerRead
31	}
32	copy(data, c.toSend[:n])
33	c.toSend = c.toSend[n:]
34	return
35}
36
37func (c *MockTerminal) Write(data []byte) (n int, err error) {
38	c.received = append(c.received, data...)
39	return len(data), nil
40}
41
42func TestClose(t *testing.T) {
43	c := &MockTerminal{}
44	ss := NewTerminal(c, "> ")
45	line, err := ss.ReadLine()
46	if line != "" {
47		t.Errorf("Expected empty line but got: %s", line)
48	}
49	if err != io.EOF {
50		t.Errorf("Error should have been EOF but got: %s", err)
51	}
52}
53
54var keyPressTests = []struct {
55	in   string
56	line string
57	err  error
58}{
59	{
60		"",
61		"",
62		io.EOF,
63	},
64	{
65		"\r",
66		"",
67		nil,
68	},
69	{
70		"foo\r",
71		"foo",
72		nil,
73	},
74	{
75		"a\x1b[Cb\r", // right
76		"ab",
77		nil,
78	},
79	{
80		"a\x1b[Db\r", // left
81		"ba",
82		nil,
83	},
84	{
85		"a\177b\r", // backspace
86		"b",
87		nil,
88	},
89}
90
91func TestKeyPresses(t *testing.T) {
92	for i, test := range keyPressTests {
93		for j := 0; j < len(test.in); j++ {
94			c := &MockTerminal{
95				toSend:       []byte(test.in),
96				bytesPerRead: j,
97			}
98			ss := NewTerminal(c, "> ")
99			line, err := ss.ReadLine()
100			if line != test.line {
101				t.Errorf("Line resulting from test %d (%d bytes per read) was '%s', expected '%s'", i, j, line, test.line)
102				break
103			}
104			if err != test.err {
105				t.Errorf("Error resulting from test %d (%d bytes per read) was '%v', expected '%v'", i, j, err, test.err)
106				break
107			}
108		}
109	}
110}
111