internal/control/output_test.go

7cc95d1fc1115f22008751a05e9e07156d49d6b0
gitbay/internal/control/output_test.go history · blame · raw

57 lines · 1969 bytes

 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{}, &SearchResult{}, &ReviewOut{}, &CheckOut{}, &CommitOut{},
20	}
21	for _, p := range payloads {
22		name := reflect.TypeOf(p).Elem().Name()
23		raw, err := json.Marshal(p)
24		if err != nil {
25			t.Errorf("%s does not marshal: %v", name, err)
26			continue
27		}
28		fresh := reflect.New(reflect.TypeOf(p).Elem()).Interface()
29		if err := json.Unmarshal(raw, fresh); err != nil {
30			t.Errorf("%s does not decode its own output: %v", name, err)
31		}
32	}
33}
34
35// TestPayloadFieldsAreTagged asserts every exported field on a payload
36// carries a json tag. Without one the key is the Go field name, which is
37// capitalised and drifts the moment the field is renamed.
38func TestPayloadFieldsAreTagged(t *testing.T) {
39	types := []any{
40		Created{}, MRCreated{}, BuildOut{}, JobOut{}, ProfileOut{}, ProfileRepo{},
41		ProfileMember{}, DashboardOut{}, DashboardItem{}, DashboardBuild{},
42		PinnedOut{}, FeedOut{}, ActivityDay{}, SearchResult{}, ReviewOut{},
43		CheckOut{}, CommitOut{}, ServerOut{},
44	}
45	for _, v := range types {
46		ty := reflect.TypeOf(v)
47		for i := 0; i < ty.NumField(); i++ {
48			f := ty.Field(i)
49			if !f.IsExported() || f.Anonymous {
50				continue
51			}
52			if _, ok := f.Tag.Lookup("json"); !ok {
53				t.Errorf("%s.%s has no json tag", ty.Name(), f.Name)
54			}
55		}
56	}
57}