package suite import "testing" // Doctrine §3: the asker subject is typed on the wire, because its meaning is // shape-dependent — a person ref in suite shape, a lowercased address in lone // shape — and nothing else in an S2 or S6 call says which shape the pair is // in. A kind the receiver does not key on must reach the caller as UNKNOWN, // never as NOT_VISIBLE, which is the one value it may act on silently. func TestSubjectRejectsUnknownKind(t *testing.T) { _, err := NewSubject("employee_number", "4471") if err == nil { t.Fatal("got nil error for an unknown subject kind, want a refusal") } } func TestSubjectRejectsEmptyValue(t *testing.T) { _, err := NewSubject(SubjectAddress, "") if err == nil { t.Fatal("got nil error for an empty subject value, want a refusal") } } // An address subject is lowercased, because that is what a lone instance keys // its members on (§3). Sending "Ana@Example.com" to a receiver storing // "ana@example.com" misses, and a miss answers NOT_VISIBLE — silently. func TestSubjectLowercasesAddress(t *testing.T) { s, err := NewSubject(SubjectAddress, "Ana@Example.COM") if err != nil { t.Fatalf("unexpected refusal: %v", err) } if s.Value != "ana@example.com" { t.Errorf("got %q, want %q", s.Value, "ana@example.com") } } // A person ref is opaque and is not touched. It is the assertion's `sub` // (home §5.3), and case may be significant in it. func TestSubjectLeavesPersonRefAlone(t *testing.T) { s, err := NewSubject(SubjectPersonRef, "PeRs_7Fa2") if err != nil { t.Fatalf("unexpected refusal: %v", err) } if s.Value != "PeRs_7Fa2" { t.Errorf("got %q, want the person ref unchanged", s.Value) } } // §6 caps an S2 question at 256 pairs. Over the cap the batch is refused, not // truncated: a silently shortened question produces a confident answer about // items nobody asked about, and the missing ones would decode as UNKNOWN // without anyone learning why. // The numbers are literal, not derived from MaxS2Pairs. Deriving both sides // from the constant tests the code's self-consistency and nothing else: // changing the constant to 512 passed the entire suite. 256 is the doctrine's // number, so 256 is what appears here. func TestS2BatchOverCapIsRefused(t *testing.T) { if err := CheckS2Batch(make([]ItemRevision, 257)); err == nil { t.Fatal("got nil error for 257 pairs, want a refusal at the doctrine's cap of 256") } } func TestS2BatchAtCapIsAccepted(t *testing.T) { if err := CheckS2Batch(make([]ItemRevision, 256)); err != nil { t.Errorf("got %v for 256 pairs, want it accepted", err) } } // And the constant itself is the doctrine's, so a later edit to it fails here // rather than quietly widening every caller's batch. func TestS2CapIsTheDoctrinesNumber(t *testing.T) { if MaxS2Pairs != 256 { t.Errorf("MaxS2Pairs is %d, want 256 (doctrine §6, memoria §6.1)", MaxS2Pairs) } }