Skip to content

Commit

Permalink
refactor(terminal): coverage test for linkSet, #87
Browse files Browse the repository at this point in the history
  • Loading branch information
ericwq committed Aug 1, 2024
1 parent 76edf92 commit f177161
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 22 deletions.
47 changes: 25 additions & 22 deletions terminal/links.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,23 @@ const (
maxIDLength = 250
)

/*
Terminal emulators traditionally use maybe a dozen or so bytes per cell. Adding hyperlinks
potentially increases it by magnitudes. As such, it's tricky to implement this feature in
terminal emulators (without consuming way too much memory), and they probably want to expose
some safety limits.
Both VTE and iTerm2 limit the URI to 2083 bytes. There's no de jure limit, the de facto is
2000-ish. Internet Explorer supports 2083.
VTE currently limits the id to 250 bytes. It's subject to change without notice, and you
should most definitely not rely on this particular number. Utilities are kindly requested
to stay way below this limit, so that a few layers of intermediate software that need to
mangle the id (e.g. add a prefix denoting their window/pane ID) still stay safe. Of course
such intermediate layers are also kindly requested to keep their added prefix at a reasonable
size. There's no limit for the id's length in iTerm2.
*/

type link struct {
url string
id string
Expand All @@ -32,23 +49,8 @@ func newLinks() *linkSet {
return v
}

// return exist link index or return new link index
func (x *linkSet) addLink(id string, url string) (index int) {
/*
Terminal emulators traditionally use maybe a dozen or so bytes per cell. Adding hyperlinks
potentially increases it by magnitudes. As such, it's tricky to implement this feature in
terminal emulators (without consuming way too much memory), and they probably want to expose
some safety limits.
Both VTE and iTerm2 limit the URI to 2083 bytes. There's no de jure limit, the de facto is
2000-ish. Internet Explorer supports 2083.
VTE currently limits the id to 250 bytes. It's subject to change without notice, and you
should most definitely not rely on this particular number. Utilities are kindly requested
to stay way below this limit, so that a few layers of intermediate software that need to
mangle the id (e.g. add a prefix denoting their window/pane ID) still stay safe. Of course
such intermediate layers are also kindly requested to keep their added prefix at a reasonable
size. There's no limit for the id's length in iTerm2.
*/
if len(url) > maxURILength-1 {
url = url[:maxURILength-1]
}
Expand All @@ -57,14 +59,15 @@ func (x *linkSet) addLink(id string, url string) (index int) {
id = id[:maxIDLength-1]
}

index = slices.IndexFunc(x.links, func(l link) bool {
return l.url == url && l.id == id
})
if len(x.links) > 0 {
idx := slices.IndexFunc(x.links, func(l link) bool {
return l.url == url && l.id == id
})

if index != -1 {
return index
if idx != -1 {
return x.links[idx].index
}
}

index = x.nextIndex
x.links = append(x.links, link{id: id, url: url, index: index})
x.nextIndex++
Expand Down
62 changes: 62 additions & 0 deletions terminal/links_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2022~2024 wangqi. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package terminal

import (
"fmt"
"strings"
"testing"
)

func TestLinkSet(t *testing.T) {
tc := []struct {
label string
id string
url string
exist []string
index int
}{
{
"add new link", "", "http://go.dev",
[]string{"http://x.y.z", "http://a.b.c"},
3,
},
{
"got exist link", "2", "http://a.b.c",
[]string{"http://x.y.z", "http://a.b.c"},
2,
},
{
"max uri length", "", strings.Repeat("x", maxURILength),
[]string{"http://x.y.z", "http://a.b.c"},
3,
},
{
"max id length", strings.Repeat("x", maxIDLength), "http://c.h.i",
[]string{"http://x.y.z", "http://a.b.c"},
3,
},
}

for _, v := range tc {
t.Run(v.label, func(t *testing.T) {
links := newLinks()

// add pre-filled link to links
for i, u := range v.exist {
id := ""
if v.id != "" {
id = fmt.Sprintf("%d", i+1)
}
links.addLink(id, u)
}

index := links.addLink(v.id, v.url)
if v.index != index {
t.Errorf("%s expect index %d, got %d\n", v.label, v.index, index)
}
})
}
}

0 comments on commit f177161

Please sign in to comment.