返回 DeepSeek-Reasonix
native_host_rpc_test.go
根目录 / desktop / native_host_rpc_test.go
1 package main
2
3 import (
4 "context"
5 "testing"
6 )
7
8 func TestRPCNativeHostMapsDialogsAndQueries(t *testing.T) {
9 a, _, shell := newHostShellBridgeForTest(t, map[string]any{
10 "host/dialog.openDirectory": map[string]any{"path": "/pick/dir"},
11 "host/dialog.openFile": map[string]any{"paths": []string{"/pick/a.png", "/pick/b.png"}},
12 "host/dialog.saveFile": map[string]any{"path": "/save/out.json"},
13 "host/dialog.message": map[string]any{"button": "Quit"},
14 "host/window.isMaximised": map[string]any{"value": true},
15 "host/screen.list": map[string]any{"screens": []map[string]any{
16 {"x": 0, "y": 0, "width": 2560, "height": 1440, "scale": 2.0, "primary": true},
17 {"x": 2560, "y": 0, "width": 1920, "height": 1080, "scale": 1.0, "primary": false},
18 }},
19 })
20 for _, method := range []string{"host/dialog.openDirectory", "host/dialog.openFile", "host/dialog.saveFile", "host/dialog.message", "host/window.isMaximised", "host/screen.list", "host/window.setPosition", "host/shell.openExternal"} {
21 shell.handle(method)
22 }
23 host := a.nativeHost()
24 ctx := context.Background()
25 if dir, err := host.OpenDirectoryDialog(ctx, nativeDialogOptions{Title: "Pick"}); err != nil || dir != "/pick/dir" {
26 t.Fatalf("openDirectory = %q, %v", dir, err)
27 }
28 if file, err := host.OpenFileDialog(ctx, nativeDialogOptions{Filters: []nativeFileFilter{{DisplayName: "Images", Pattern: "*.png"}}}); err != nil || file != "/pick/a.png" {
29 t.Fatalf("openFile = %q, %v", file, err)
30 }
31 if path, err := host.SaveFileDialog(ctx, nativeDialogOptions{DefaultFilename: "out.json"}); err != nil || path != "/save/out.json" {
32 t.Fatalf("saveFile = %q, %v", path, err)
33 }
34 if button, err := host.MessageDialog(ctx, nativeMessageOptions{Type: nativeDialogQuestion, Buttons: []string{"Quit", "Cancel"}}); err != nil || button != "Quit" {
35 t.Fatalf("message = %q, %v", button, err)
36 }
37 if !host.WindowIsMaximised(ctx) {
38 t.Fatal("isMaximised must follow the shell reply")
39 }
40 screens, err := host.Screens(ctx)
41 if err != nil || len(screens) != 2 || !screens[0].Primary || screens[0].Width != 2560 || screens[1].Scale != 1 {
42 t.Fatalf("screens = %+v, %v", screens, err)
43 }
44 host.SetWindowPosition(ctx, 10, 20)
45 host.OpenExternal(ctx, "https://example.test")
46 calls := shell.methods()
47 if len(calls) != 8 || calls[6] != "host/window.setPosition" || calls[7] != "host/shell.openExternal" {
48 t.Fatalf("shell calls = %v", calls)
49 }
50 }
51
52 func TestRPCNativeHostToleratesAnUnansweredShell(t *testing.T) {
53 a, _, _ := newHostShellBridgeForTest(t, nil)
54 host := a.nativeHost()
55 ctx := context.Background()
56 if dir, err := host.OpenDirectoryDialog(ctx, nativeDialogOptions{}); err == nil || dir != "" {
57 t.Fatalf("an unhandled dialog must fail, got %q, %v", dir, err)
58 }
59 if host.WindowIsMaximised(ctx) {
60 t.Fatal("an unhandled query must read as false")
61 }
62 if _, err := host.Screens(ctx); err == nil {
63 t.Fatal("an unhandled screen list must surface an error")
64 }
65 }
66
66 lines GO