WIP! A BB-style forum, on the ATmosphere!
We're still working... we'll be back soon when we have something to show off!
node
typescript
hono
htmx
atproto
1import { describe, it, expect } from "vitest";
2import { readFileSync } from "node:fs";
3import { join } from "node:path";
4import { parse as parseYaml } from "yaml";
5import { globSync } from "glob";
6
7const LEXICONS_DIR = join(import.meta.dirname, "..", "lexicons");
8const yamlFiles = globSync("**/*.yaml", { cwd: LEXICONS_DIR });
9
10describe("lexicon definitions", () => {
11 it("finds at least one lexicon file", () => {
12 expect(yamlFiles.length).toBeGreaterThan(0);
13 });
14
15 describe.each(yamlFiles)("%s", (file) => {
16 const content = readFileSync(join(LEXICONS_DIR, file), "utf-8");
17 const parsed = parseYaml(content);
18
19 it("has lexicon version 1", () => {
20 expect(parsed).toHaveProperty("lexicon", 1);
21 });
22
23 it("has an id field", () => {
24 expect(parsed).toHaveProperty("id");
25 expect(typeof parsed.id).toBe("string");
26 });
27
28 it("has a defs object", () => {
29 expect(parsed).toHaveProperty("defs");
30 expect(typeof parsed.defs).toBe("object");
31 });
32
33 it("has an id that matches the file path", () => {
34 // space/atbb/post.yaml -> space.atbb.post
35 const expectedId = file.replace(/\.yaml$/, "").replace(/\//g, ".");
36 expect(parsed.id).toBe(expectedId);
37 });
38 });
39});
40
41describe("lexicon uniqueness", () => {
42 it("has no duplicate lexicon ids", () => {
43 const ids = yamlFiles.map((file) => {
44 const content = readFileSync(join(LEXICONS_DIR, file), "utf-8");
45 return parseYaml(content).id;
46 });
47 const unique = new Set(ids);
48 expect(unique.size).toBe(ids.length);
49 });
50});
51
52describe("record key conventions", () => {
53 const recordLexicons = yamlFiles
54 .map((file) => {
55 const content = readFileSync(join(LEXICONS_DIR, file), "utf-8");
56 return { file, parsed: parseYaml(content) };
57 })
58 .filter(({ parsed }) => parsed.defs?.main?.type === "record");
59
60 it.each(recordLexicons.map(({ file, parsed }) => [file, parsed]))(
61 "%s has a valid record key type",
62 (_file, parsed) => {
63 const key = parsed.defs.main.key;
64 expect(["tid", "literal:self"]).toContain(key);
65 }
66 );
67});
68
69describe("extensible fields use knownValues", () => {
70 it("modAction.action uses knownValues, not enum", () => {
71 const content = readFileSync(
72 join(LEXICONS_DIR, "space/atbb/modAction.yaml"),
73 "utf-8"
74 );
75 const parsed = parseYaml(content);
76 const actionField =
77 parsed.defs.main.record?.properties?.action;
78 expect(actionField).toBeDefined();
79 expect(actionField).not.toHaveProperty("enum");
80 expect(actionField).toHaveProperty("knownValues");
81 });
82});
83
84describe("strongRef definitions", () => {
85 it("strongRef has uri and cid fields", () => {
86 const content = readFileSync(
87 join(LEXICONS_DIR, "com/atproto/repo/strongRef.yaml"),
88 "utf-8"
89 );
90 const parsed = parseYaml(content);
91 const mainDef = parsed.defs.main;
92 expect(mainDef.properties).toHaveProperty("uri");
93 expect(mainDef.properties).toHaveProperty("cid");
94 expect(mainDef.required).toContain("uri");
95 expect(mainDef.required).toContain("cid");
96 });
97});