Artifact 4e29fe6383eb73804045a62ac179e6954cba230536cbd29e913a5ffbb7776615:
- File
internal/evt/evt_test.go
— part of check-in
[3aef7f3211]
at
2026-08-24 15:57:31
on branch trunk
— RFC 0005: dagnats already has the triggers; correct the record
I probed HTTP and concluded dagnats had no scheduler. Wrong lens — triggers are NATS and KV native. It has cron, subject, webhook, durable HTTP, worker-contributed kinds and debounce. So quarry builds none of that: it owes well-named subjects, and the vocabulary IS the hierarchy. (user: dmestas, size: 4293) [annotate] [blame] [check-ins using]
package evt import "testing" // A subscription naming a noun selects every action on it, including ones // added after the subscription was written. That is the entire argument for // noun-and-action over Gitea's one-name-per-verb, so it is the thing to pin. func TestANounSelectsEveryActionOnIt(t *testing.T) { if !TicketClosed.Matches("ticket") { t.Error(`"ticket" does not select ticket.closed`) } if !TicketOpened.Matches("ticket") { t.Error(`"ticket" does not select ticket.opened`) } if !TicketClosed.Matches("ticket.closed") { t.Error("an exact kind does not select itself") } // Precision is available where it is wanted. if TicketOpened.Matches("ticket.closed") { t.Error("ticket.closed selected ticket.opened") } // A noun does not reach across nouns, however similar the names. if LandingOpened.Matches("ticket") { t.Error("a noun selected another noun's event") } // A pattern naming a noun that does not exist selects nothing rather // than everything — the failure of a typo must be silence, not a // firehose. if TicketClosed.Matches("tickets") || TicketClosed.Matches("") { t.Error("a bad pattern matched") } } // The bus is a one-hour window, so what happens to a missed event depends on // whether it can be re-derived from the store. Getting this classification // wrong is how an operational fact — a failed mirror pull — silently does not // happen, so each noun is asserted rather than the rule restated. func TestDerivedEventsAreExactlyTheOnesTheStoreHolds(t *testing.T) { for _, k := range []Kind{CheckinCreated, BranchMoved, TagCreated, TicketClosed, WikiEdited, TechnoteCreated, ForumPosted, LandingAccepted} { if !k.Derived() { t.Errorf("%s is a reading of stored artifacts and should be derived", k) } } // None of these is in the DAG: missing one loses the fact, so each // must be recorded in OLTP as it is raised. for _, k := range []Kind{CICompleted, MirrorFailed, RepoCreated, AccountCaps, CloneCloned} { if k.Derived() { t.Errorf("%s is not in the store and must not be treated as re-derivable", k) } } } // An unknown name is refused where the subscription is written. A pipeline // that never runs and a pipeline that runs and fails look nothing alike to // the person waiting for it. func TestUnknownKindsAreRefused(t *testing.T) { for _, bad := range []Kind{"ticket.exploded", "issue.opened", "checkin", ""} { if bad.Valid() { t.Errorf("%q was accepted into the vocabulary", bad) } } for _, k := range All { if !k.Valid() { t.Errorf("%s is in All but not Valid", k) } if k.Noun() == "" || k.Action() == "" { t.Errorf("%s is not noun.action", k) } } } // The vocabulary is a published interface: a name in someone else's pipeline // definition. This pins the set so a rename is a deliberate act with a // failing test attached, not a refactor that quietly breaks every store. func TestTheVocabularyIsFixed(t *testing.T) { if got, want := len(All), 35; got != want { t.Errorf("the vocabulary changed size: %d, was %d — if deliberate, say so in RFC 0005", got, want) } want := []string{"checkin", "branch", "tag", "ticket", "wiki", "technote", "forum", "landing", "ci", "mirror", "repo", "account", "clone"} got := Nouns() if len(got) != len(want) { t.Fatalf("nouns = %v, want %v", got, want) } for i := range want { if got[i] != want[i] { t.Fatalf("nouns = %v, want %v", got, want) } } } // The subject is the subscription interface: dagnats triggers take a NATS // subject filter, so the vocabulary has to survive being taken apart by // wildcards. A noun or action containing a dot would silently break every // filter that assumed the shape. func TestEverySubjectHasExactlyFiveTokens(t *testing.T) { for _, k := range All { got := k.Subject("quarry") if n := len(splitDots(got)); n != 5 { t.Errorf("%s -> %s has %d tokens, want 5 (zit.evt.repo.noun.action)", k, got, n) } } if got, want := LandingOpened.Subject("quarry"), "zit.evt.quarry.landing.opened"; got != want { t.Errorf("subject = %q, want %q", got, want) } } func splitDots(s string) []string { var out []string start := 0 for i := 0; i < len(s); i++ { if s[i] == '.' { out = append(out, s[start:i]) start = i + 1 } } return append(out, s[start:]) }