eleven / messenger Public

Clone
git clone https://amadan.net/eleven/messenger

Plain git — no account needed to clone.

Download

Download this file

1import XCTest
2@testable import LChatCore
3
4// đŸ¤– Card contract tests — the Swift third of test/event-vectors/cards.json
5// (web: test/cards.test.mjs; Go: internal/bot/card_test.go). The fixture is a
6// byte-identical copy of the canonical file (drift-checked by the web test).
7// A failure here means native has drifted from the contract: fix the
8// implementation, never the vector, unless the schema is deliberately
9// changing on all three platforms in one PR.
10final class CardVectorTests: XCTestCase {
11 struct VectorFile: Decodable {
12 let schema: Int
13 let vectors: [Vector]
14 }
15 struct Vector: Decodable {
16 let name: String
17 let card: JSONValue?
18 let want: JSONValue?
19 }
20
21 func loadVectors() throws -> VectorFile {
22 let url = try XCTUnwrap(Bundle.module.url(forResource: "Fixtures/cards-vector", withExtension: "json"),
23 "cards-vector.json fixture missing")
24 return try JSONDecoder().decode(VectorFile.self, from: Data(contentsOf: url))
25 }
26
27 func testVectors() throws {
28 let file = try loadVectors()
29 XCTAssertEqual(file.schema, Card.schema, "vector file schema must match Card.schema")
30 for v in file.vectors {
31 let got = Card.normalize(v.card)
32 if let want = v.want, want != .null {
33 guard let got else {
34 XCTFail("\(v.name): normalized to nil, want \(want)")
35 continue
36 }
37 XCTAssertEqual(got.canonical(), want, v.name)
38 } else {
39 XCTAssertNil(got, "\(v.name): must fail closed")
40 }
41 }
42 }
43
44 // The payload decode carries a card through and ignores its absence.
45 func testPayloadCarriesCard() throws {
46 let json = #"{"name":"Dawn","text":"fallback","card":{"schema":1,"blocks":[{"b":"text","text":"hi"}]}}"#
47 let p = try JSONDecoder().decode(MessagePayload.self, from: Data(json.utf8))
48 let card = Card.normalize(p.card)
49 XCTAssertEqual(card?.blocks, [.text("hi")])
50
51 let plain = try JSONDecoder().decode(MessagePayload.self, from: Data(#"{"name":"A","text":"x"}"#.utf8))
52 XCTAssertNil(plain.card)
53 XCTAssertNil(Card.normalize(plain.card))
54 }
55
56 // Normalize is idempotent through the canonical form.
57 func testIdempotent() throws {
58 let file = try loadVectors()
59 for v in file.vectors {
60 guard let once = Card.normalize(v.card) else { continue }
61 XCTAssertEqual(Card.normalize(once.canonical()), once, v.name)
62 }
63 }
64}
65