<commit_before>package textview

import (
	"reflect"
	"testing"

	"github.com/elves/elvish/cli/el"
	"github.com/elves/elvish/cli/term"
	"github.com/elves/elvish/edit/ui"
	"github.com/elves/elvish/styled"
)

var bb = ui.NewBufferBuilder

var renderTests = []el.RenderTest{
	{
		Name: "text fits entirely",
		Given: &Widget{State: State{
			Lines: []string{"line 1", "line 2", "line 3"}}},
		Width: 10, Height: 4,
		Want: bb(10).
			WritePlain("line 1").Newline().
			WritePlain("line 2").Newline().
			WritePlain("line 3").Buffer(),
	},
	{
		Name: "text cropped horizontally",
		Given: &Widget{State: State{
			Lines: []string{"a very long line"}}},
		Width: 10, Height: 4,
		Want: bb(10).
			WritePlain("a very lon").Buffer(),
	},
	{
		Name: "text cropped vertically",
		Given: &Widget{State: State{
			Lines: []string{"line 1", "line 2", "line 3"}}},
		Width: 10, Height: 2,
		Want: bb(10).
			WritePlain("line 1").Newline().
			WritePlain("line 2").Buffer(),
	},
	{
		Name: "text cropped vertically, with scrollbar",
		Given: &Widget{
			Scrollable: true,
			State: State{
				Lines: []string{"line 1", "line 2", "line 3", "line 4"}}},
		Width: 10, Height: 2,
		Want: bb(10).
			WritePlain("line 1   ").
			WriteStyled(styled.MakeText(" ", "inverse", "magenta")).Newline().
			WritePlain("line 2   ").
			WriteStyled(styled.MakeText("│", "magenta")).Buffer(),
	},
	{
		Name: "State.First adjusted to fit text",
		Given: &Widget{State: State{
			First: 2,
			Lines: []string{"line 1", "line 2", "line 3"}}},
		Width: 10, Height: 3,
		Want: bb(10).
			WritePlain("line 1").Newline().
			WritePlain("line 2").Newline().
			WritePlain("line 3").Buffer(),
	},
}

func TestRender(t *testing.T) {
	el.TestRender(t, renderTests)
}

var handleTests = []struct {
	name        string
	widget      *Widget
	event       term.Event
	wantHandled bool
	wantState   State
}{
	{
		"up doing nothing when not scrollable",
		&Widget{
			State: State{Lines: []string{"1", "2", "3", "4"}, First: 1}},
		term.K(ui.Up),
		false,
		State{Lines: []string{"1", "2", "3", "4"}, First: 1},
	},
	{
		"up moving window up when scrollable",
		&Widget{
			Scrollable: true,
			State:      State{Lines: []string{"1", "2", "3", "4"}, First: 1}},
		term.K(ui.Up),
		true,
		State{Lines: []string{"1", "2", "3", "4"}, First: 0},
	},
	{
		"up doing nothing when already at top",
		&Widget{
			Scrollable: true,
			State:      State{Lines: []string{"1", "2", "3", "4"}, First: 0}},
		term.K(ui.Up),
		true,
		State{Lines: []string{"1", "2", "3", "4"}, First: 0},
	},
	{
		"down moving window down when scrollable",
		&Widget{
			Scrollable: true,
			State:      State{Lines: []string{"1", "2", "3", "4"}, First: 1}},
		term.K(ui.Down),
		true,
		State{Lines: []string{"1", "2", "3", "4"}, First: 2},
	},
	{
		"down doing nothing when already at bottom",
		&Widget{
			Scrollable: true,
			State:      State{Lines: []string{"1", "2", "3", "4"}, First: 3}},
		term.K(ui.Down),
		true,
		State{Lines: []string{"1", "2", "3", "4"}, First: 3},
	},
	{
		"overlay",
		&Widget{
			OverlayHandler: el.MapHandler{term.K('a'): func() {}},
		},
		term.K('a'),
		true,
		State{},
	},
}

func TestHandle(t *testing.T) {
	for _, test := range handleTests {
		t.Run(test.name, func(t *testing.T) {
			w := test.widget
			handled := w.Handle(test.event)
			if handled != test.wantHandled {
				t.Errorf("got handled %v, want %v", handled, test.wantHandled)
			}
			if !reflect.DeepEqual(w.State, test.wantState) {
				t.Errorf("got state %v, want %v", w.State, test.wantState)
			}
		})
	}
}

func TestCopyState(t *testing.T) {
	state := State{Lines: []string{"a", "b", "c"}, First: 1}
	w := &Widget{State: state}
	copied := w.CopyState()
	if !reflect.DeepEqual(copied, state) {
		t.Errorf("Got copied state %v, want %v", copied, state)
	}
}<commit_msg>cli/el/textview: Rewrite TestHandle using el.TestHandle.<commit_after>package textview

import (
	"reflect"
	"testing"

	"github.com/elves/elvish/cli/el"
	"github.com/elves/elvish/cli/term"
	"github.com/elves/elvish/edit/ui"
	"github.com/elves/elvish/styled"
)

var bb = ui.NewBufferBuilder

var renderTests = []el.RenderTest{
	{
		Name: "text fits entirely",
		Given: &Widget{State: State{
			Lines: []string{"line 1", "line 2", "line 3"}}},
		Width: 10, Height: 4,
		Want: bb(10).
			WritePlain("line 1").Newline().
			WritePlain("line 2").Newline().
			WritePlain("line 3").Buffer(),
	},
	{
		Name: "text cropped horizontally",
		Given: &Widget{State: State{
			Lines: []string{"a very long line"}}},
		Width: 10, Height: 4,
		Want: bb(10).
			WritePlain("a very lon").Buffer(),
	},
	{
		Name: "text cropped vertically",
		Given: &Widget{State: State{
			Lines: []string{"line 1", "line 2", "line 3"}}},
		Width: 10, Height: 2,
		Want: bb(10).
			WritePlain("line 1").Newline().
			WritePlain("line 2").Buffer(),
	},
	{
		Name: "text cropped vertically, with scrollbar",
		Given: &Widget{
			Scrollable: true,
			State: State{
				Lines: []string{"line 1", "line 2", "line 3", "line 4"}}},
		Width: 10, Height: 2,
		Want: bb(10).
			WritePlain("line 1   ").
			WriteStyled(styled.MakeText(" ", "inverse", "magenta")).Newline().
			WritePlain("line 2   ").
			WriteStyled(styled.MakeText("│", "magenta")).Buffer(),
	},
	{
		Name: "State.First adjusted to fit text",
		Given: &Widget{State: State{
			First: 2,
			Lines: []string{"line 1", "line 2", "line 3"}}},
		Width: 10, Height: 3,
		Want: bb(10).
			WritePlain("line 1").Newline().
			WritePlain("line 2").Newline().
			WritePlain("line 3").Buffer(),
	},
}

func TestRender(t *testing.T) {
	el.TestRender(t, renderTests)
}

var handleTests = []el.HandleTest{
	{
		Name: "up doing nothing when not scrollable",
		Given: &Widget{
			State: State{Lines: []string{"1", "2", "3", "4"}, First: 1}},
		Event: term.K(ui.Up),

		WantUnhandled: true,
	},
	{
		Name: "up moving window up when scrollable",
		Given: &Widget{
			Scrollable: true,
			State:      State{Lines: []string{"1", "2", "3", "4"}, First: 1}},
		Event: term.K(ui.Up),

		WantNewState: State{Lines: []string{"1", "2", "3", "4"}, First: 0},
	},
	{
		Name: "up doing nothing when already at top",
		Given: &Widget{
			Scrollable: true,
			State:      State{Lines: []string{"1", "2", "3", "4"}, First: 0}},
		Event: term.K(ui.Up),

		WantNewState: State{Lines: []string{"1", "2", "3", "4"}, First: 0},
	},
	{
		Name: "down moving window down when scrollable",
		Given: &Widget{
			Scrollable: true,
			State:      State{Lines: []string{"1", "2", "3", "4"}, First: 1}},
		Event: term.K(ui.Down),

		WantNewState: State{Lines: []string{"1", "2", "3", "4"}, First: 2},
	},
	{
		Name: "down doing nothing when already at bottom",
		Given: &Widget{
			Scrollable: true,
			State:      State{Lines: []string{"1", "2", "3", "4"}, First: 3}},
		Event: term.K(ui.Down),

		WantNewState: State{Lines: []string{"1", "2", "3", "4"}, First: 3},
	},
	{
		Name: "overlay",
		Given: &Widget{
			OverlayHandler: el.MapHandler{term.K('a'): func() {}},
		},
		Event: term.K('a'),

		WantNewState: State{},
	},
}

func TestHandle(t *testing.T) {
	el.TestHandle(t, handleTests)
}

func TestCopyState(t *testing.T) {
	state := State{Lines: []string{"a", "b", "c"}, First: 1}
	w := &Widget{State: state}
	copied := w.CopyState()
	if !reflect.DeepEqual(copied, state) {
		t.Errorf("Got copied state %v, want %v", copied, state)
	}
}
{'fraction_non_alphanumeric': 0.21448087431693988, 'fraction_numerical': 0.02663934426229508, 'mean_word_length': 3.708038585209003, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '341487', 'n_tokens_mistral': 3262, 'n_tokens_neox': 2814, 'n_words': 713}