Monorepo for Tangled tangled.org
3

Configure Feed

Select the types of activity you want to include in your feed.

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 test("renders issue with long author handle", async () => { 91 const data = createIssueData(avatarDataUri, { 92 authorHandle: "very.very.long.tangled.org", 93 }); 94 const validated = issueCardSchema.parse(data); 95 await renderAndSave( 96 h(IssueCard, validated), 97 "issue-card-long-handle.png", 98 ); 99 }); 100}); 101 102describe("pull request cards", () => { 103 test("renders open pull request", async () => { 104 const data = createPullRequestData(avatarDataUri); 105 const validated = pullRequestCardSchema.parse(data); 106 await renderAndSave(h(PullRequestCard, validated), "pull-request-card.png"); 107 }); 108 109 test("renders merged pull request", async () => { 110 const data = createPullRequestData(avatarDataUri, { 111 pullRequestNumber: 2, 112 status: "merged", 113 title: "Implement OAuth2 authentication flow", 114 filesChanged: 5, 115 additions: 342, 116 deletions: 28, 117 }); 118 const validated = pullRequestCardSchema.parse(data); 119 await renderAndSave( 120 h(PullRequestCard, validated), 121 "pull-request-card-merged.png", 122 ); 123 }); 124 125 test("renders closed pull request", async () => { 126 const data = createPullRequestData(avatarDataUri, { 127 pullRequestNumber: 3, 128 status: "closed", 129 title: "WIP: Experimental feature", 130 }); 131 const validated = pullRequestCardSchema.parse(data); 132 await renderAndSave( 133 h(PullRequestCard, validated), 134 "pull-request-card-closed.png", 135 ); 136 }); 137 138 test("renders pull request with long title", async () => { 139 const data = createLongTitlePullRequestData(avatarDataUri, { 140 pullRequestNumber: 42, 141 }); 142 const validated = pullRequestCardSchema.parse(data); 143 await renderAndSave( 144 h(PullRequestCard, validated), 145 "pull-request-card-long-title.png", 146 ); 147 }); 148 149 test("renders pull request with long author handle", async () => { 150 const data = createPullRequestData(avatarDataUri, { 151 authorHandle: "very.very.long.tangled.org", 152 }); 153 const validated = pullRequestCardSchema.parse(data); 154 await renderAndSave( 155 h(PullRequestCard, validated), 156 "pull-request-card-long-handle.png", 157 ); 158 }); 159});