135 lines
4.0 KiB
Go
135 lines
4.0 KiB
Go
package pixel
|
|
|
|
import (
|
|
"slices"
|
|
"testing"
|
|
)
|
|
|
|
func TestEditModel(t *testing.T) {
|
|
var s editState
|
|
s.reset("hello")
|
|
if s.caret != 5 || s.anchor != 5 {
|
|
t.Fatalf("reset caret %d anchor %d", s.caret, s.anchor)
|
|
}
|
|
s.anchor = 1
|
|
s.replace([]rune("EY"), 0)
|
|
if string(s.text) != "hEY" || s.caret != 3 || !s.changed {
|
|
t.Fatalf("replace gave %q caret %d", string(s.text), s.caret)
|
|
}
|
|
s.replace([]rune("1234"), 5)
|
|
if string(s.text) != "hEY12" {
|
|
t.Fatalf("maxLen kept %q", string(s.text))
|
|
}
|
|
s.erase(9, -3)
|
|
if string(s.text) != "" || s.caret != 0 {
|
|
t.Fatalf("erase clamps: %q caret %d", string(s.text), s.caret)
|
|
}
|
|
s.restore(&s.undo, &s.redo)
|
|
s.restore(&s.undo, &s.redo)
|
|
if string(s.text) != "hEY" || len(s.redo) != 2 {
|
|
t.Fatalf("two undos gave %q, redo %d", string(s.text), len(s.redo))
|
|
}
|
|
s.restore(&s.redo, &s.undo)
|
|
if string(s.text) != "hEY12" {
|
|
t.Fatalf("redo gave %q", string(s.text))
|
|
}
|
|
for range 150 {
|
|
s.replace([]rune("x"), 0)
|
|
}
|
|
if len(s.undo) != 100 || len(s.redo) != 0 {
|
|
t.Fatalf("history %d undo %d redo, want 100 and 0", len(s.undo), len(s.redo))
|
|
}
|
|
}
|
|
|
|
func TestClean(t *testing.T) {
|
|
if got := string(clean("a\tb\r\nc\x07d", false)); got != "a b cd" {
|
|
t.Fatalf("one line: %q", got)
|
|
}
|
|
if got := string(clean("a\r\nb\nc", true)); got != "a\nb\nc" {
|
|
t.Fatalf("multiline: %q", got)
|
|
}
|
|
}
|
|
|
|
func TestWords(t *testing.T) {
|
|
rs := []rune("foo bar, 像素x")
|
|
if wordRight(rs, 0) != 3 || wordRight(rs, 3) != 8 || wordRight(rs, 8) != 9 || wordRight(rs, 10) != 12 {
|
|
t.Fatalf("wordRight %d %d %d %d", wordRight(rs, 0), wordRight(rs, 3), wordRight(rs, 8), wordRight(rs, 10))
|
|
}
|
|
if wordLeft(rs, len(rs)) != 12 || wordLeft(rs, 8) != 5 || wordLeft(rs, 5) != 0 {
|
|
t.Fatalf("wordLeft %d %d %d", wordLeft(rs, len(rs)), wordLeft(rs, 8), wordLeft(rs, 5))
|
|
}
|
|
if a, b := wordAt(rs, 6); a != 5 || b != 8 {
|
|
t.Fatalf("wordAt 6 = %d..%d", a, b)
|
|
}
|
|
if a, b := wordAt(rs, 11); a != 10 || b != 12 {
|
|
t.Fatalf("wordAt in CJK = %d..%d", a, b)
|
|
}
|
|
if a, b := wordAt(nil, 0); a != 0 || b != 0 {
|
|
t.Fatal("wordAt on empty text")
|
|
}
|
|
}
|
|
|
|
func TestEditLayoutAndCaret(t *testing.T) {
|
|
rs := []rune("ab cd\nef")
|
|
lines := editLayout(rs, Measure("ab "), true)
|
|
want := []editLine{{0, 2}, {3, 5}, {6, 8}}
|
|
if !slices.Equal(lines, want) {
|
|
t.Fatalf("layout %v, want %v", lines, want)
|
|
}
|
|
if x, li := caretAt(lines, rs, 3); x != 0 || li != 1 {
|
|
t.Fatalf("caret at wrap is %d on line %d", x, li)
|
|
}
|
|
if x, li := caretAt(lines, rs, 5); x != Measure("cd") || li != 1 {
|
|
t.Fatalf("caret before newline is %d on line %d", x, li)
|
|
}
|
|
if lineEnd(lines, 0) != 2 || lineEnd(lines, 1) != 5 || lineEnd(lines, 2) != 8 {
|
|
t.Fatalf("lineEnd %d %d %d", lineEnd(lines, 0), lineEnd(lines, 1), lineEnd(lines, 2))
|
|
}
|
|
if hitLine(lines, rs, 2, 0) != 6 || hitLine(lines, rs, 2, 999) != 8 || hitLine(lines, rs, 0, Measure("a")) != 1 {
|
|
t.Fatal("hitLine misses rune boundaries")
|
|
}
|
|
gap := []rune("ab cd")
|
|
gl := editLayout(gap, Measure("ab "), true)
|
|
if x, li := caretAt(gl, gap, 3); li != 0 || x != Measure("ab") {
|
|
t.Fatalf("caret in the break gap at %d on line %d", x, li)
|
|
}
|
|
if one := editLayout(rs, 1, false); !slices.Equal(one, []editLine{{0, 8}}) {
|
|
t.Fatalf("single line layout %v", one)
|
|
}
|
|
}
|
|
|
|
func TestKeepVisible(t *testing.T) {
|
|
var s editState
|
|
s.keepVisible(100, 120, 40)
|
|
if s.scroll != 61 {
|
|
t.Fatalf("scroll %d, want 61", s.scroll)
|
|
}
|
|
s.keepVisible(10, 120, 40)
|
|
if s.scroll != 10 {
|
|
t.Fatalf("scroll back %d, want 10", s.scroll)
|
|
}
|
|
s.keepVisible(10, 30, 40)
|
|
if s.scroll != 0 {
|
|
t.Fatalf("short text scroll %d, want 0", s.scroll)
|
|
}
|
|
}
|
|
|
|
func TestMaskedComposition(t *testing.T) {
|
|
var s editState
|
|
s.reset("ab")
|
|
s.compose = []rune("ni")
|
|
if got := string(s.view('*', true)); got != "****" {
|
|
t.Fatalf("masked view with composition = %q", got)
|
|
}
|
|
if got := string(s.view(0, true)); got != "abni" {
|
|
t.Fatalf("plain view with composition = %q", got)
|
|
}
|
|
}
|
|
|
|
func TestMultilineLeavesRoomForCaret(t *testing.T) {
|
|
rs := []rune("ab")
|
|
if lines := editLayout(rs, Measure("ab"), true); len(lines) != 2 {
|
|
t.Fatalf("text as wide as the field: %v, want a wrap before the caret column", lines)
|
|
}
|
|
}
|