// Copyright (c) 2026 Storm Dragon // Authors: Storm Dragon, Angus Kola // SPDX-License-Identifier: GPL-3.0-or-later package ocr import "testing" func TestCursorUnicodeLinesAndEngineWordOrder(t *testing.T) { result := Result{Text: "é e\u0301\n\nאב 42", Words: []Word{ {Text: "é", Span: Span{0, 1}}, {Text: "e\u0301", Span: Span{2, 4}}, {Text: "אב", Span: Span{6, 8}}, {Text: "42", Span: Span{9, 11}}, }} cursor := NewCursor(result) if got := cursor.Current(LineUnit); got.Text != "é e\u0301" || got.Offset != 0 || got.Cursor != 0 { t.Fatalf("initial: %+v", got) } if got := cursor.Move(WordUnit, 1); got.Text != "e\u0301" || got.Offset != 2 || got.Cursor != 2 { t.Fatalf("combining word: %+v", got) } if got := cursor.Move(Character, 1); got.Text != "\u0301" || got.Offset != 3 { t.Fatalf("combining character: %+v", got) } if got := cursor.Move(LineUnit, 1); got.Text != "" || got.Offset != 5 || got.Cursor != 0 { t.Fatalf("blank paragraph: %+v", got) } if got := cursor.Move(LineUnit, 1); got.Text != "אב 42" || got.Offset != 9 || got.Cursor != 3 { t.Fatalf("preserved column: %+v", got) } if got := cursor.Move(WordUnit, -1); got.Text != "אב" || got.Offset != 6 { t.Fatalf("RTL engine order: %+v", got) } if got := cursor.Move(DocumentEnd, 0); got.Offset != 11 || got.Cursor != 5 || got.Text != "אב 42" { t.Fatalf("end: %+v", got) } if got := cursor.Move(Character, 1); got.Moved || got.Offset != 11 { t.Fatalf("past end: %+v", got) } cursor.Move(DocumentStart, 0) if got := cursor.Move(Character, -1); got.Moved || got.Offset != 0 { t.Fatalf("before start: %+v", got) } } func TestCursorLineEndsSeparatorsAndEmptyDocument(t *testing.T) { cursor := NewCursor(Result{Text: "one\ntwo\n"}) if got := cursor.Move(LineEnd, 0); got.Offset != 3 || got.Text != "\n" || got.Cursor != 3 { t.Fatalf("line end: %+v", got) } if got := cursor.Move(Character, 1); got.Offset != 4 || got.Text != "t" || got.Line != "two" || got.Cursor != 0 { t.Fatalf("cross separator: %+v", got) } if got := cursor.Move(DocumentEnd, 0); got.Offset != 8 || got.Line != "" || got.Cursor != 0 { t.Fatalf("trailing blank: %+v", got) } if got := NewCursor(Result{}).Move(Character, 1); got.Offset != 0 || got.Text != "" || got.Moved { t.Fatalf("empty: %+v", got) } }