1package main
2
3import (
4 "strings"
5 "testing"
6)
7
8// TestEventLayouts pins wire offsets that the X11 protocol defines, checked
9// against the event containers (independent of generated code).
10func TestEventLayouts(t *testing.T) {
11 want := map[string]map[string]int{
12 "xproto.MapRequest": {"Parent": 4, "Window": 8},
13 "xproto.ConfigureRequest": {"StackMode": 1, "Parent": 4, "Window": 8, "Sibling": 12, "X": 16, "Y": 18, "Width": 20, "Height": 22, "BorderWidth": 24, "ValueMask": 26},
14 "xproto.KeymapNotify": {"Keys": 1},
15 "xproto.ClientMessage": {"Format": 1, "Window": 4, "Type": 8, "Data": 12},
16 "xproto.PropertyNotify": {"Window": 4, "Atom": 8, "Time": 12, "State": 16},
17 "xfixes.SelectionNotify": {"Subtype": 1, "Window": 4, "Owner": 8, "Selection": 12, "Timestamp": 16, "SelectionTimestamp": 20},
18 "shape.Notify": {"ShapeKind": 1, "AffectedWindow": 4, "ServerTime": 16, "Shaped": 20},
19 }
20 copies := 0
21 for _, m := range testModules(t) {
22 events, err := resolveEvents(m)
23 if err != nil {
24 t.Fatal(err)
25 }
26 for _, e := range events {
27 if e.Copy != nil {
28 copies++
29 if e.C != e.Copy.C {
30 t.Errorf("%s: copy does not share its source layout", e.Name)
31 }
32 continue
33 }
34 exp := want[m.Pkg+"."+e.Name]
35 for _, mem := range e.C.Members {
36 if off, ok := exp[mem.Method]; ok {
37 if mem.Static != off {
38 t.Errorf("%s.%s.%s at %d want %d", m.Pkg, e.Name, mem.Method, mem.Static, off)
39 }
40 delete(exp, mem.Method)
41 }
42 }
43 if len(exp) != 0 {
44 t.Errorf("%s.%s: missing %v", m.Pkg, e.Name, exp)
45 }
46 }
47 }
48 if copies != 5 {
49 t.Errorf("xproto has 5 eventcopy, got %d", copies)
50 }
51}
52
53func TestEventGeneratorRejects(t *testing.T) {
54 for _, tc := range []struct{ body, want string }{
55 {`<event name="E" number="200" xge="true"><pad bytes="22"/></event>`, "xge evtype"},
56 {`<event name="E" number="1"><field type="CARD32" name="a"/></event>`, "header data byte"},
57 {`<eventcopy name="C" number="3" ref="Missing"/>`, "unknown event"},
58 {`<event name="E" number="2"><pad bytes="1"/><list type="CARD8" name="l"><fieldref>n</fieldref></list></event>`, "first 32 bytes"},
59 } {
60 // Some constructs are already rejected by the parser; either stage must
61 // fail with a source location.
62 n, err := parseXML("ev.xml", strings.NewReader(`<xcb header="test" extension-name="Test" extension-xname="TEST">`+tc.body+`</xcb>`))
63 if err == nil {
64 var ms []*Module
65 if ms, err = resolveModules([]*Node{n}); err != nil {
66 t.Fatal(err)
67 }
68 _, err = resolveEvents(ms[0])
69 }
70 if err == nil || !strings.Contains(err.Error(), tc.want) || !strings.Contains(err.Error(), "ev.xml:1:") {
71 t.Errorf("%s: got %v", tc.want, err)
72 }
73 }
74}
75
76func TestErrorConstNames(t *testing.T) {
77 for in, want := range map[string]string{"Window": "BadWindow", "BadRegion": "BadRegion", "PictFormat": "BadPictFormat", "IDChoice": "BadIDChoice"} {
78 if got := errorConst(in); got != want {
79 t.Errorf("%s => %s want %s", in, got, want)
80 }
81 }
82}