aboutsummaryrefslogtreecommitdiff
path: root/cmd/krino/display_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/krino/display_test.go')
-rw-r--r--cmd/krino/display_test.go35
1 files changed, 24 insertions, 11 deletions
diff --git a/cmd/krino/display_test.go b/cmd/krino/display_test.go
index 0f4cf90..a1b199c 100644
--- a/cmd/krino/display_test.go
+++ b/cmd/krino/display_test.go
@@ -6,15 +6,24 @@ import (
"fmt"
"strings"
"testing"
- "unicode"
"unicode/utf8"
)
-// firstUnsafe names the first thing in s a terminal could act on - a
-// control character (a newline too, unless allowNewline), a Unicode
-// bidirectional control, a line or paragraph separator, or invalid UTF-8 -
-// or returns "" when there is none. It is built from Go's Unicode tables,
-// not from display's own ranges, so it can catch a class display misses.
+// terminalRunes is the test's own, hand-written list of code points a
+// terminal acts on or that reorder what it shows: C0 controls, DEL, C1
+// controls, the Unicode bidirectional marks, embeddings, overrides and
+// isolates (UAX #9), and the line and paragraph separators. It is written
+// out, not derived from Go's tables or from display, so it can catch a
+// class display misses (re-review term F3).
+var terminalRunes = [][2]rune{
+ {0x00, 0x1f}, {0x7f, 0x9f},
+ {0x061c, 0x061c}, {0x200e, 0x200f}, {0x202a, 0x202e}, {0x2066, 0x2069},
+ {0x2028, 0x2029},
+}
+
+// firstUnsafe names the first thing in s from terminalRunes (a newline
+// allowed when allowNewline), or invalid UTF-8, or returns "" when there is
+// none.
func firstUnsafe(s string, allowNewline bool) string {
if !utf8.ValidString(s) {
return "invalid UTF-8"
@@ -23,8 +32,10 @@ func firstUnsafe(s string, allowNewline bool) string {
if r == '\n' && allowNewline {
continue
}
- if unicode.IsControl(r) || unicode.Is(unicode.Bidi_Control, r) || unicode.In(r, unicode.Zl, unicode.Zp) {
- return fmt.Sprintf("%U", r)
+ for _, span := range terminalRunes {
+ if r >= span[0] && r <= span[1] {
+ return fmt.Sprintf("%U", r)
+ }
}
}
return ""
@@ -92,8 +103,8 @@ func TestReviewEscapesHostileNames(t *testing.T) {
}
// TestSafeWriterEscapesButKeepsNewlines: everything written to stderr goes
-// through display line by line, so a quoted file name cannot act on the
-// terminal while messages keep their lines (review M5).
+// through display, so a quoted file name cannot act on the terminal; each
+// Write keeps its final newline (review M5).
func TestSafeWriterEscapesButKeepsNewlines(t *testing.T) {
var b strings.Builder
in := "a\x1b[2J\nb\u202e\n"
@@ -101,7 +112,9 @@ func TestSafeWriterEscapesButKeepsNewlines(t *testing.T) {
if err != nil || n != len(in) {
t.Fatalf("Write = %d, %v", n, err)
}
- if got, want := b.String(), "a\\x1b[2J\nb\\u202e\n"; got != want {
+ // Only the Write's final newline ends a line; one inside it came from
+ // quoted text and could fake a line of krino's own (re-review term F1).
+ if got, want := b.String(), "a\\x1b[2J\\x0ab\\u202e\n"; got != want {
t.Errorf("wrote %q, want %q", got, want)
}
}