internal/control/output_test.go
59 lines · 2077 bytes
2 symbols in this file
1package control
2
3import (
4 "encoding/json"
5 "reflect"
6 "testing"
7)
8
9// TestNamedPayloadsRoundTrip asserts that every named payload survives a
10// marshal/unmarshal cycle with no field lost. A field added to the struct
11// but given no JSON tag, or given one that collides with another, drops
12// silently: the command still emits, the client still decodes, and the
13// value is simply missing. This is the failure #126 is about.
14func TestNamedPayloadsRoundTrip(t *testing.T) {
15 payloads := []any{
16 &Created{}, &MRCreated{}, &IssueShow{}, &MRShow{},
17 &BuildOut{}, &JobOut{}, &ProfileOut{}, &ProfileRepo{}, &ProfileMember{},
18 &DashboardOut{}, &DashboardItem{}, &DashboardBuild{}, &PinnedOut{},
19 &FeedOut{}, &ActivityDay{}, &DepsOut{}, &DepBehind{}, &ForkOut{}, &BookmarkOut{},
20 &SearchResult{}, &ReviewOut{}, &CheckOut{}, &CommitOut{},
21 }
22 for _, p := range payloads {
23 name := reflect.TypeOf(p).Elem().Name()
24 raw, err := json.Marshal(p)
25 if err != nil {
26 t.Errorf("%s does not marshal: %v", name, err)
27 continue
28 }
29 fresh := reflect.New(reflect.TypeOf(p).Elem()).Interface()
30 if err := json.Unmarshal(raw, fresh); err != nil {
31 t.Errorf("%s does not decode its own output: %v", name, err)
32 }
33 }
34}
35
36// TestPayloadFieldsAreTagged asserts every exported field on a payload
37// carries a json tag. Without one the key is the Go field name, which is
38// capitalised and drifts the moment the field is renamed.
39func TestPayloadFieldsAreTagged(t *testing.T) {
40 types := []any{
41 Created{}, MRCreated{}, BuildOut{}, JobOut{}, ProfileOut{}, ProfileRepo{},
42 ProfileMember{}, DashboardOut{}, DashboardItem{}, DashboardBuild{},
43 PinnedOut{}, FeedOut{}, ActivityDay{}, DepsOut{}, DepBehind{}, ForkOut{}, BookmarkOut{},
44 SearchResult{}, ReviewOut{},
45 CheckOut{}, CommitOut{}, ServerOut{},
46 }
47 for _, v := range types {
48 ty := reflect.TypeOf(v)
49 for i := 0; i < ty.NumField(); i++ {
50 f := ty.Field(i)
51 if !f.IsExported() || f.Anonymous {
52 continue
53 }
54 if _, ok := f.Tag.Lookup("json"); !ok {
55 t.Errorf("%s.%s has no json tag", ty.Name(), f.Name)
56 }
57 }
58 }
59}