This repository has no description
1import { test, describe, beforeAll } from "bun:test";
2import { writeFileSync, mkdirSync, readFileSync } from "fs";
3import { join } from "path";
4import { h, type VNode } from "preact";
5import { renderCard } from "../lib/render";
6import { RepositoryCard } from "../components/cards/repository";
7import { IssueCard } from "../components/cards/issue";
8import { PullRequestCard } from "../components/cards/pull-request";
9import {
10 repositoryCardSchema,
11 issueCardSchema,
12 pullRequestCardSchema,
13} from "../validation";
14import {
15 createRepoData,
16 createIssueData,
17 createPullRequestData,
18 createLongTitleIssueData,
19 createLongTitlePullRequestData,
20} from "./fixtures";
21
22const outputDir = join(process.cwd(), "output");
23let avatarDataUri: string;
24
25const loadAvatar = (): string => {
26 const avatarPath = join(
27 process.cwd(),
28 "src",
29 "__tests__",
30 "assets",
31 "avatar.jpg",
32 );
33 const avatarBase64 = readFileSync(avatarPath).toString("base64");
34 return `data:image/jpeg;base64,${avatarBase64}`;
35};
36
37beforeAll(() => {
38 mkdirSync(outputDir, { recursive: true });
39 avatarDataUri = loadAvatar();
40});
41
42const savePng = (filename: string, buffer: Uint8Array) => {
43 writeFileSync(join(outputDir, filename), buffer);
44};
45
46const saveSvg = (filename: string, svg: string) => {
47 writeFileSync(join(outputDir, filename), svg);
48};
49
50const renderAndSave = async <P>(component: VNode<P>, filename: string) => {
51 const { svg, png } = await renderCard(component as VNode);
52 saveSvg(filename.replace(".png", ".svg"), svg);
53 savePng(filename, png);
54};
55
56describe("repository card", () => {
57 test("renders repository card", async () => {
58 const data = createRepoData(avatarDataUri);
59 const validated = repositoryCardSchema.parse(data);
60 await renderAndSave(h(RepositoryCard, validated), "repository-card.png");
61 });
62});
63
64describe("issue cards", () => {
65 test("renders open issue", async () => {
66 const data = createIssueData(avatarDataUri);
67 const validated = issueCardSchema.parse(data);
68 await renderAndSave(h(IssueCard, validated), "issue-card.png");
69 });
70
71 test("renders closed issue", async () => {
72 const data = createIssueData(avatarDataUri, {
73 issueNumber: 5,
74 status: "closed",
75 labels: [{ name: "wontfix", color: "#6a737d" }],
76 reactionCount: 2,
77 });
78 const validated = issueCardSchema.parse(data);
79 await renderAndSave(h(IssueCard, validated), "issue-card-closed.png");
80 });
81
82 test("renders issue with long title", async () => {
83 const data = createLongTitleIssueData(avatarDataUri, {
84 issueNumber: 42,
85 });
86 const validated = issueCardSchema.parse(data);
87 await renderAndSave(h(IssueCard, validated), "issue-card-long-title.png");
88 });
89});
90
91describe("pull request cards", () => {
92 test("renders open pull request", async () => {
93 const data = createPullRequestData(avatarDataUri);
94 const validated = pullRequestCardSchema.parse(data);
95 await renderAndSave(h(PullRequestCard, validated), "pull-request-card.png");
96 });
97
98 test("renders merged pull request", async () => {
99 const data = createPullRequestData(avatarDataUri, {
100 pullRequestNumber: 2,
101 status: "merged",
102 title: "Implement OAuth2 authentication flow",
103 filesChanged: 5,
104 additions: 342,
105 deletions: 28,
106 });
107 const validated = pullRequestCardSchema.parse(data);
108 await renderAndSave(
109 h(PullRequestCard, validated),
110 "pull-request-card-merged.png",
111 );
112 });
113
114 test("renders closed pull request", async () => {
115 const data = createPullRequestData(avatarDataUri, {
116 pullRequestNumber: 3,
117 status: "closed",
118 title: "WIP: Experimental feature",
119 });
120 const validated = pullRequestCardSchema.parse(data);
121 await renderAndSave(
122 h(PullRequestCard, validated),
123 "pull-request-card-closed.png",
124 );
125 });
126
127 test("renders pull request with long title", async () => {
128 const data = createLongTitlePullRequestData(avatarDataUri, {
129 pullRequestNumber: 42,
130 });
131 const validated = pullRequestCardSchema.parse(data);
132 await renderAndSave(
133 h(PullRequestCard, validated),
134 "pull-request-card-long-title.png",
135 );
136 });
137});