main f2d166b

scene_same_test.go RawHistoryFolder

1package ports
2
3import (
4	"reflect"
5	"testing"
6
7	"github.com/stretchr/testify/assert"
8)
9
10func sameSceneBase() Scene {
11	return Scene{
12		Security:     SecurityState{Generation: 1},
13		Output:       "A",
14		Seq:          1,
15		OutputWidth:  100,
16		OutputHeight: 50,
17		Scale:        1,
18		Background:   "#000000",
19		Border:       Border{Width: 2, Active: "#ffffff", Inactive: "#222222"},
20		Windows:      []SceneWindow{{ID: 1, Rect: Rect{X: 1, W: 10, H: 10}}},
21		Separators:   []Separator{{Rect: Rect{W: 1, H: 10}}},
22		DropHints:    []Rect{{W: 5, H: 5}},
23		Layers:       []SceneLayer{{ID: 9, Rect: Rect{W: 100, H: 5}}},
24		Capture:      &SceneCapture{Shown: 1, Excluded: []WindowID{3}},
25
26		Outline:           &SelectionOutline{Rect: Rect{W: 20, H: 10}, Width: 2, Radius: 8, Active: true},
27		Flash:             &FocusFlash{Rect: Rect{W: 20, H: 10}, Width: 2, Color: "#ff0000", Alpha: 0.6},
28		CaptureIndicators: []CaptureIndicator{{Rect: Rect{W: 4, H: 4}}},
29		HintLabels:        []HintLabel{{Rect: Rect{X: 3, Y: 4}, Text: "fj", Typed: 1}},
30	}
31}
32
33func TestSceneSameAs(t *testing.T) {
34	base := sameSceneBase()
35
36	same := sameSceneBase()
37	same.Seq = 99
38	assert.True(t, base.SameAs(same), "Seq alone must not matter")
39	assert.True(t, Scene{}.SameAs(Scene{Seq: 3}))
40
41	for name, edit := range map[string]func(*Scene){
42		"position hint":     func(s *Scene) { s.PositionHint.Opacity = 1 },
43		"outline nil":       func(s *Scene) { s.Outline = nil },
44		"outline rect":      func(s *Scene) { s.Outline.Rect.X++ },
45		"outline width":     func(s *Scene) { s.Outline.Width++ },
46		"outline radius":    func(s *Scene) { s.Outline.Radius++ },
47		"outline active":    func(s *Scene) { s.Outline.Active = false },
48		"flash nil":         func(s *Scene) { s.Flash = nil },
49		"flash rect":        func(s *Scene) { s.Flash.Rect.X++ },
50		"flash width":       func(s *Scene) { s.Flash.Width++ },
51		"flash color":       func(s *Scene) { s.Flash.Color = "#ffffff" },
52		"flash alpha":       func(s *Scene) { s.Flash.Alpha = 0.2 },
53		"window rect":       func(s *Scene) { s.Windows[0].Rect.X++ },
54		"window fade":       func(s *Scene) { s.Windows[0].Fade = 0.5 },
55		"window zoom":       func(s *Scene) { s.Windows[0].Zoom = 0.9 },
56		"window count":      func(s *Scene) { s.Windows = nil },
57		"security":          func(s *Scene) { s.Security.Generation++ },
58		"background":        func(s *Scene) { s.Background = "#111111" },
59		"border":            func(s *Scene) { s.Border.Width++ },
60		"output":            func(s *Scene) { s.Output = "B" },
61		"size":              func(s *Scene) { s.OutputWidth++ },
62		"scale":             func(s *Scene) { s.Scale = 2 },
63		"off":               func(s *Scene) { s.Off = true },
64		"clip":              func(s *Scene) { s.WorkspaceClip.W = 1 },
65		"tile inset":        func(s *Scene) { s.TileInset.Bottom = 1 },
66		"dim":               func(s *Scene) { s.Dim = 0.5 },
67		"dim behind":        func(s *Scene) { s.DimBehind = true },
68		"separator":         func(s *Scene) { s.Separators[0].Active = true },
69		"drop hint":         func(s *Scene) { s.DropHints[0].W++ },
70		"layer":             func(s *Scene) { s.Layers[0].Rect.H++ },
71		"indicator":         func(s *Scene) { s.CaptureIndicators[0].Pill = true },
72		"hint style":        func(s *Scene) { s.HintStyle.Size = 24 },
73		"hint capture":      func(s *Scene) { s.HintStyle.Capture = true },
74		"excluded":          func(s *Scene) { s.Capture.Excluded[0] = 4 },
75		"transform":         func(s *Scene) { s.Transform = 1 },
76		"capture shown":     func(s *Scene) { s.Capture.Shown++ },
77		"capture session":   func(s *Scene) { s.Capture.Session++ },
78		"capture workspace": func(s *Scene) { s.Capture.Workspace++ },
79		"capture window":    func(s *Scene) { s.Capture.Window++ },
80		"capture revision":  func(s *Scene) { s.Capture.Revision++ },
81		"capture nil":       func(s *Scene) { s.Capture = nil },
82		"capture scene":     func(s *Scene) { s.CaptureScene = &Scene{} },
83	} {
84		t.Run(name, func(t *testing.T) {
85			o := sameSceneBase()
86			edit(&o)
87			assert.False(t, base.SameAs(o))
88			assert.False(t, o.SameAs(base))
89		})
90	}
91
92	both := sameSceneBase()
93	both.CaptureScene = &Scene{}
94	other := sameSceneBase()
95	other.CaptureScene = &Scene{}
96	assert.False(t, both.SameAs(other), "a capture scene is never the same")
97}
98
99// TestSceneSameAsCoversEveryField fails when Scene gains or loses a field:
100// update Scene.SameAs, then this count.
101func TestSceneSameAsCoversEveryField(t *testing.T) {
102	// 25 with Animating, which SameAs intentionally does not compare: it
103	// only schedules the next frame, it draws nothing.
104	const fields = 27
105	assert.Equal(t, fields, len(reflect.VisibleFields(reflect.TypeOf(Scene{}))),
106		"Scene fields changed: update Scene.SameAs (and TestSceneSameAs), then this count")
107}
108
109// TestSceneCaptureSameAsCoversEveryField fails when SceneCapture gains or
110// loses a field: update Scene.SameAs, then this count.
111func TestSceneCaptureSameAsCoversEveryField(t *testing.T) {
112	const fields = 6
113	assert.Equal(t, fields, len(reflect.VisibleFields(reflect.TypeOf(SceneCapture{}))),
114		"SceneCapture fields changed: update Scene.SameAs (and TestSceneSameAs), then this count")
115}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 25

Tags 10

↑↓ moveenter openesc close