mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-06-01 03:09:37 +08:00
- 修复 WebView2 zoom factor 跨线程调用风险,切回窗口线程执行并增加 recover 与超时保护 - 完善 Redis 命令结果 JSON-safe 兜底,避免复杂返回值格式化触发程序崩溃 - 调整 Windows driver-agent 校验逻辑,仅读取 PE Machine 字段判断架构兼容性 - 避免 COFF string table EOF 被误判为无效 Windows 可执行文件,修复驱动在线安装和本地导入失败 - 补充窗口缩放、Redis 返回值和驱动代理 PE 校验回归测试
135 lines
4.3 KiB
Go
135 lines
4.3 KiB
Go
//go:build windows
|
||
|
||
package app
|
||
|
||
import (
|
||
"context"
|
||
"strings"
|
||
"sync/atomic"
|
||
"testing"
|
||
)
|
||
|
||
// fakeChromium 模仿 *edge.Chromium 的接口:只需要 exported 的 PutZoomFactor(float64) 方法。
|
||
// 用于在不依赖真实 wails / WebView2 的情况下验证反射路径。
|
||
type fakeChromium struct {
|
||
called atomic.Int32
|
||
last atomic.Value // float64
|
||
}
|
||
|
||
func (f *fakeChromium) PutZoomFactor(factor float64) {
|
||
f.called.Add(1)
|
||
f.last.Store(factor)
|
||
}
|
||
|
||
type fakeWindow struct {
|
||
invoked atomic.Int32
|
||
}
|
||
|
||
func (f *fakeWindow) Invoke(fn func()) {
|
||
f.invoked.Add(1)
|
||
fn()
|
||
}
|
||
|
||
// fakeFrontend 模仿 wails 的 internal/frontend/desktop/windows.Frontend:
|
||
// unexported 字段 chromium/mainWindow 分别模仿 *edge.Chromium 和 *windows.Window。
|
||
// 反射代码不依赖具体类型名,只检查 method signature。
|
||
type fakeFrontend struct {
|
||
chromium *fakeChromium
|
||
mainWindow *fakeWindow
|
||
}
|
||
|
||
type panicChromium struct{}
|
||
|
||
func (p *panicChromium) PutZoomFactor(float64) {
|
||
panic("webview2 zoom reset failed")
|
||
}
|
||
|
||
type panicFrontend struct {
|
||
chromium *panicChromium
|
||
}
|
||
|
||
// 测试必须用 wails 一致的 string key "frontend" 作为 context.WithValue 的 key,
|
||
// 否则反射拿不到。go vet 会警告 string key,用本地 stringContextKey 帮助函数封装来抑制。
|
||
// 这层封装等价于直接传字符串字面量,行为完全一致。
|
||
func stringContextKey(key string) any {
|
||
type contextKeyAlias = string
|
||
return contextKeyAlias(key)
|
||
}
|
||
|
||
func TestResetWebViewZoomFactorCallsPutZoomFactor(t *testing.T) {
|
||
chromium := &fakeChromium{}
|
||
window := &fakeWindow{}
|
||
ctx := context.WithValue(context.Background(), stringContextKey("frontend"), &fakeFrontend{chromium: chromium, mainWindow: window})
|
||
|
||
if err := resetWebViewZoomFactor(ctx, 1.0); err != nil {
|
||
t.Fatalf("expected reset to succeed against fake frontend, got %v", err)
|
||
}
|
||
if got := window.invoked.Load(); got != 1 {
|
||
t.Fatalf("expected reset to run through mainWindow.Invoke exactly once, got %d", got)
|
||
}
|
||
if got := chromium.called.Load(); got != 1 {
|
||
t.Fatalf("expected PutZoomFactor called exactly once, got %d", got)
|
||
}
|
||
if got, _ := chromium.last.Load().(float64); got != 1.0 {
|
||
t.Fatalf("expected factor 1.0, got %v", got)
|
||
}
|
||
}
|
||
|
||
func TestResetWebViewZoomFactorErrorsWhenChromiumFieldMissing(t *testing.T) {
|
||
type fakeFrontendWithoutChromium struct {
|
||
other string
|
||
}
|
||
ctx := context.WithValue(context.Background(), stringContextKey("frontend"), &fakeFrontendWithoutChromium{})
|
||
err := resetWebViewZoomFactor(ctx, 1.0)
|
||
if err == nil {
|
||
t.Fatal("expected error when chromium field is missing, got nil")
|
||
}
|
||
if !strings.Contains(err.Error(), "chromium") {
|
||
t.Fatalf("expected error to mention chromium, got %v", err)
|
||
}
|
||
}
|
||
|
||
func TestResetWebViewZoomFactorErrorsWhenChromiumNil(t *testing.T) {
|
||
ctx := context.WithValue(context.Background(), stringContextKey("frontend"), &fakeFrontend{chromium: nil, mainWindow: &fakeWindow{}})
|
||
err := resetWebViewZoomFactor(ctx, 1.0)
|
||
if err == nil {
|
||
t.Fatal("expected error when chromium is nil, got nil")
|
||
}
|
||
if !strings.Contains(err.Error(), "nil") {
|
||
t.Fatalf("expected error to mention nil, got %v", err)
|
||
}
|
||
}
|
||
|
||
func TestResetWebViewZoomFactorErrorsWhenMainWindowNil(t *testing.T) {
|
||
ctx := context.WithValue(context.Background(), stringContextKey("frontend"), &fakeFrontend{chromium: &fakeChromium{}, mainWindow: nil})
|
||
err := resetWebViewZoomFactor(ctx, 1.0)
|
||
if err == nil {
|
||
t.Fatal("expected error when mainWindow is nil, got nil")
|
||
}
|
||
if !strings.Contains(err.Error(), "mainWindow") {
|
||
t.Fatalf("expected error to mention mainWindow, got %v", err)
|
||
}
|
||
}
|
||
|
||
func TestResetWebViewZoomFactorErrorsWhenFrontendMissing(t *testing.T) {
|
||
err := resetWebViewZoomFactor(context.Background(), 1.0)
|
||
if err == nil {
|
||
t.Fatal("expected error when frontend not in ctx, got nil")
|
||
}
|
||
if !strings.Contains(err.Error(), "frontend") {
|
||
t.Fatalf("expected error to mention frontend, got %v", err)
|
||
}
|
||
}
|
||
|
||
func TestResetWebViewZoomFactorRecoversFromPutZoomFactorPanic(t *testing.T) {
|
||
ctx := context.WithValue(context.Background(), stringContextKey("frontend"), &panicFrontend{chromium: &panicChromium{}})
|
||
|
||
err := resetWebViewZoomFactor(ctx, 1.0)
|
||
if err == nil {
|
||
t.Fatal("expected panic to be converted to error, got nil")
|
||
}
|
||
if !strings.Contains(err.Error(), "panic") {
|
||
t.Fatalf("expected error to mention panic, got %v", err)
|
||
}
|
||
}
|