mirror of
https://github.com/ollama/ollama.git
synced 2025-11-11 11:17:39 +01:00
* app: add code for macOS and Windows apps under 'app' * app: add readme * app: windows and linux only for now * ci: fix ui CI validation --------- Co-authored-by: jmorganca <jmorganca@gmail.com>
148 lines
4.9 KiB
Go
148 lines
4.9 KiB
Go
//go:build windows || darwin
|
|
|
|
package tools
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/ollama/ollama/app/ui/responses"
|
|
)
|
|
|
|
func makeTestPage(url string) *responses.Page {
|
|
return &responses.Page{
|
|
URL: url,
|
|
Title: "Title " + url,
|
|
Text: "Body for " + url,
|
|
Lines: []string{"line1", "line2", "line3"},
|
|
Links: map[int]string{0: url},
|
|
FetchedAt: time.Now(),
|
|
}
|
|
}
|
|
|
|
func TestBrowser_Scroll_AppendsOnlyPageStack(t *testing.T) {
|
|
b := NewBrowser(&responses.BrowserStateData{PageStack: []string{}, ViewTokens: 1024, URLToPage: map[string]*responses.Page{}})
|
|
p1 := makeTestPage("https://example.com/1")
|
|
b.savePage(p1)
|
|
initialStackLen := len(b.state.Data.PageStack)
|
|
initialMapLen := len(b.state.Data.URLToPage)
|
|
|
|
bo := NewBrowserOpen(b)
|
|
// Scroll without id — should push only to PageStack
|
|
_, _, err := bo.Execute(t.Context(), map[string]any{"loc": float64(1), "num_lines": float64(1)})
|
|
if err != nil {
|
|
t.Fatalf("scroll execute failed: %v", err)
|
|
}
|
|
|
|
if got, want := len(b.state.Data.PageStack), initialStackLen+1; got != want {
|
|
t.Fatalf("page stack length = %d, want %d", got, want)
|
|
}
|
|
if got, want := len(b.state.Data.URLToPage), initialMapLen; got != want {
|
|
t.Fatalf("url_to_page length changed = %d, want %d", got, want)
|
|
}
|
|
}
|
|
|
|
func TestBrowserOpen_UseCacheByURL(t *testing.T) {
|
|
b := NewBrowser(&responses.BrowserStateData{PageStack: []string{}, ViewTokens: 1024, URLToPage: map[string]*responses.Page{}})
|
|
bo := NewBrowserOpen(b)
|
|
|
|
p := makeTestPage("https://example.com/cached")
|
|
b.state.Data.URLToPage[p.URL] = p
|
|
initialStackLen := len(b.state.Data.PageStack)
|
|
initialMapLen := len(b.state.Data.URLToPage)
|
|
|
|
_, _, err := bo.Execute(t.Context(), map[string]any{"id": p.URL})
|
|
if err != nil {
|
|
t.Fatalf("open cached execute failed: %v", err)
|
|
}
|
|
|
|
if got, want := len(b.state.Data.PageStack), initialStackLen+1; got != want {
|
|
t.Fatalf("page stack length = %d, want %d", got, want)
|
|
}
|
|
if got, want := len(b.state.Data.URLToPage), initialMapLen; got != want {
|
|
t.Fatalf("url_to_page length changed = %d, want %d", got, want)
|
|
}
|
|
}
|
|
|
|
func TestDisplayPage_InvalidLoc(t *testing.T) {
|
|
b := NewBrowser(&responses.BrowserStateData{PageStack: []string{}, ViewTokens: 1024, URLToPage: map[string]*responses.Page{}})
|
|
p := makeTestPage("https://example.com/x")
|
|
// ensure lines are set
|
|
p.Lines = []string{"a", "b"}
|
|
_, err := b.displayPage(p, 0, 10, -1)
|
|
if err == nil || !strings.Contains(err.Error(), "invalid location") {
|
|
t.Fatalf("expected invalid location error, got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestBrowserOpen_LinkId_UsesCacheAndAppends(t *testing.T) {
|
|
b := NewBrowser(&responses.BrowserStateData{PageStack: []string{}, ViewTokens: 1024, URLToPage: map[string]*responses.Page{}})
|
|
// Seed a main page with a link id 0 to a linked URL
|
|
main := makeTestPage("https://example.com/main")
|
|
linked := makeTestPage("https://example.com/linked")
|
|
main.Links = map[int]string{0: linked.URL}
|
|
// Save the main page (adds to PageStack and URLToPage)
|
|
b.savePage(main)
|
|
// Pre-cache the linked page so open by id avoids network
|
|
b.state.Data.URLToPage[linked.URL] = linked
|
|
|
|
initialStackLen := len(b.state.Data.PageStack)
|
|
initialMapLen := len(b.state.Data.URLToPage)
|
|
|
|
bo := NewBrowserOpen(b)
|
|
_, _, err := bo.Execute(t.Context(), map[string]any{"id": float64(0)})
|
|
if err != nil {
|
|
t.Fatalf("open by link id failed: %v", err)
|
|
}
|
|
|
|
if got, want := len(b.state.Data.PageStack), initialStackLen+1; got != want {
|
|
t.Fatalf("page stack length = %d, want %d", got, want)
|
|
}
|
|
if got, want := len(b.state.Data.URLToPage), initialMapLen; got != want {
|
|
t.Fatalf("url_to_page length changed = %d, want %d", got, want)
|
|
}
|
|
if last := b.state.Data.PageStack[len(b.state.Data.PageStack)-1]; last != linked.URL {
|
|
t.Fatalf("last page in stack = %s, want %s", last, linked.URL)
|
|
}
|
|
}
|
|
|
|
func TestWrapLines_PreserveAndWidth(t *testing.T) {
|
|
long := strings.Repeat("word ", 50)
|
|
text := "Line1\n\n" + long + "\nLine3"
|
|
lines := wrapLines(text, 40)
|
|
|
|
// Ensure empty line preserved at index 1
|
|
if lines[1] != "" {
|
|
t.Fatalf("expected preserved empty line at index 1, got %q", lines[1])
|
|
}
|
|
// All lines should be <= 40 chars
|
|
for i, l := range lines {
|
|
if len(l) > 40 {
|
|
t.Fatalf("line %d exceeds width: %d > 40", i, len(l))
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDisplayPage_FormatHeaderAndLines(t *testing.T) {
|
|
b := NewBrowser(&responses.BrowserStateData{PageStack: []string{}, ViewTokens: 1024, URLToPage: map[string]*responses.Page{}})
|
|
p := &responses.Page{
|
|
URL: "https://example.com/x",
|
|
Title: "Example",
|
|
Lines: []string{"URL: https://example.com/x", "A", "B", "C"},
|
|
}
|
|
out, err := b.displayPage(p, 3, 0, 2)
|
|
if err != nil {
|
|
t.Fatalf("displayPage failed: %v", err)
|
|
}
|
|
if !strings.HasPrefix(out, "[3] Example(") {
|
|
t.Fatalf("header not formatted as expected: %q", out)
|
|
}
|
|
if !strings.Contains(out, "L0:\n") {
|
|
t.Fatalf("missing L0 label: %q", out)
|
|
}
|
|
if !strings.Contains(out, "L1: URL: https://example.com/x\n") || !strings.Contains(out, "L2: A\n") {
|
|
t.Fatalf("missing expected line numbers/content: %q", out)
|
|
}
|
|
}
|