Snapshots render in a fresh child process: pixels no longer depend on test order
This commit is contained in:
3 files changed
+35
-2
No files matched your search
@@ -54,7 +54,7 @@ testdata/snapshots/ <os>/<name>-<light|dark>.png
|
||||
- `ui.NewTester` drives click, keys, typing. Assert values, not existence.
|
||||
- Every component: one `snapshot(t, name, w, h, view)` call (light and dark). Refresh with `go test -run <Name> -update .`
|
||||
- Run `go vet ./... && go test ./...` before reporting done.
|
||||
- Snapshots assume the default test order. MyGo shares its path-mask cache across a process, and its own chevrons are not snapped, so `-shuffle` can shift a few pixels (docs/upstream.md).
|
||||
- Each snapshot test renders in a fresh child process (snapshot_test.go), because MyGo's path-mask cache is process-wide. Order and neighbours never change pixels; `-run <Name> -update` is safe.
|
||||
|
||||
## Gallery page
|
||||
|
||||
|
||||
+1
-1
@@ -35,4 +35,4 @@ PRD 第 2 节要求公开接口不足时向上游提交扩展。以下缺口在
|
||||
| `SelectBase` 高亮无设置接口 | `ui/base.go:260` | Select |
|
||||
| `TextInputBase` 无只读开关与占位符 | `ui/editor.go:139,734,811` | TextInput 只读模式、CommandPalette |
|
||||
| `ui.Stepper` 禁用时仍可步进,固定 9 位取整 | `ui/indicators.go:216`、`ui/widgets.go` `snap` | NumberInput(已改为自绘) |
|
||||
| 路径遮罩缓存按四分之一像素取键,进程内共享 | `ui/path.go:189-210` | 自绘路径以 `internal.Snap` 对齐;MyGo 自绘的箭头(Outline 等)无法对齐,快照依赖测试运行顺序,`-shuffle` 下 TreeTable 快照会出现 6 像素差异 |
|
||||
| 路径遮罩缓存按四分之一像素取键,进程内共享 | `ui/path.go:189-210` | 自绘路径以 `internal.Snap` 对齐;MyGo 自绘的箭头(Outline 等)无法对齐;快照测试因此在独立子进程中渲染,结果与测试顺序无关 |
|
||||
@@ -6,9 +6,12 @@ import (
|
||||
"image"
|
||||
"image/png"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/egoist/mygo/ui"
|
||||
@@ -22,9 +25,18 @@ func snapshot(t *testing.T, name string, w, h int, view func(c *ui.Context)) {
|
||||
snapshotAfter(t, name, w, h, view, nil)
|
||||
}
|
||||
|
||||
// snapshotChild marks a process that renders snapshots itself.
|
||||
const snapshotChild = "MUJICA_SNAPSHOT_CHILD"
|
||||
|
||||
var snapshotRan sync.Map
|
||||
|
||||
// snapshotAfter is snapshot with drive sending input before the capture.
|
||||
func snapshotAfter(t *testing.T, name string, w, h int, view func(c *ui.Context), drive func(tt *ui.Tester)) {
|
||||
t.Helper()
|
||||
if os.Getenv(snapshotChild) == "" {
|
||||
snapshotInChild(t)
|
||||
return
|
||||
}
|
||||
for _, m := range []Mode{Light, Dark} {
|
||||
ready := false
|
||||
tt := ui.NewTester(func(c *ui.Context) {
|
||||
@@ -64,6 +76,27 @@ func snapshotAfter(t *testing.T, name string, w, h int, view func(c *ui.Context)
|
||||
}
|
||||
}
|
||||
|
||||
// snapshotInChild reruns the test alone in a fresh process; MyGo's path cache is process-wide.
|
||||
func snapshotInChild(t *testing.T) {
|
||||
t.Helper()
|
||||
if _, done := snapshotRan.LoadOrStore(t.Name(), true); done {
|
||||
return
|
||||
}
|
||||
parts := strings.Split(t.Name(), "/")
|
||||
for i, p := range parts {
|
||||
parts[i] = "^" + regexp.QuoteMeta(p) + "$"
|
||||
}
|
||||
args := []string{"-test.run=" + strings.Join(parts, "/"), "-test.count=1"}
|
||||
if *update {
|
||||
args = append(args, "-update")
|
||||
}
|
||||
cmd := exec.Command(os.Args[0], args...)
|
||||
cmd.Env = append(os.Environ(), snapshotChild+"=1")
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
t.Fatalf("snapshot child failed: %v\n%s", err, out)
|
||||
}
|
||||
}
|
||||
|
||||
func encode(t *testing.T, img image.Image) []byte {
|
||||
t.Helper()
|
||||
var b bytes.Buffer
|
||||
|
||||
Reference in new issue
Block a user