Skip to content

Commit 053088d

Browse files
authored
test: add more tests to hydrate flow (#578)
<!-- 👋 Hi, thanks for sending a PR to template-typescript-node-package! 💖. Please fill out all fields below and make sure each item is true and [x] checked. Otherwise we may not be able to review your PR. --> ## PR Checklist - [x] Addresses an existing open issue: fixes #447 - [x] That issue was marked as [`status: accepting prs`](https://github.com/JoshuaKGoldberg/template-typescript-node-package/issues?q=is%3Aopen+is%3Aissue+label%3A%22status%3A+accepting+prs%22) - [x] Steps in [CONTRIBUTING.md](https://github.com/JoshuaKGoldberg/template-typescript-node-package/blob/main/.github/CONTRIBUTING.md) were taken ## Overview Added more tests across the `getHydrationDefaults` flow, also addressing a bug where `readTitleFromReadme` only matched the first word of the title.
1 parent ab5ccc2 commit 053088d

File tree

5 files changed

+129
-2
lines changed

5 files changed

+129
-2
lines changed

src/hydrate/readFileSafe.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { describe, expect, it, vi } from "vitest";
2+
3+
import { readFileSafe } from "./readFileSafe.js";
4+
5+
const mockReadFile = vi.fn();
6+
7+
vi.mock("node:fs/promises", () => ({
8+
get default() {
9+
return {
10+
get readFile() {
11+
return mockReadFile;
12+
},
13+
};
14+
},
15+
}));
16+
17+
describe("readFundingIfExists", () => {
18+
it("outputs the file content as string when it exists", async () => {
19+
mockReadFile.mockResolvedValue("File content as string");
20+
const result = await readFileSafe("/path/to/file.ext", "fallback");
21+
expect(result).toBe("File content as string");
22+
});
23+
24+
it("returns fallback when readFile fails", async () => {
25+
mockReadFile.mockRejectedValue("Oops");
26+
const result = await readFileSafe("/path/to/nowhere.ext", "fallback");
27+
expect(result).toBe("fallback");
28+
});
29+
});
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { describe, expect, it, vi } from "vitest";
2+
3+
import { getHydrationDefaults } from "./getHydrationDefaults.js";
4+
5+
const mockReadFileSafe = vi.fn();
6+
7+
vi.mock("../readFileSafe.js", () => ({
8+
get readFileSafe() {
9+
return mockReadFileSafe;
10+
},
11+
}));
12+
13+
const mockReadFundingIfExists = vi.fn();
14+
15+
vi.mock("./readFundingIfExists.js", () => ({
16+
get readFundingIfExists() {
17+
return mockReadFundingIfExists;
18+
},
19+
}));
20+
21+
const mockReadOwnerFromGitRemote = vi.fn();
22+
23+
vi.mock("./readOwnerFromGitRemote.js", () => ({
24+
get readOwnerFromGitRemote() {
25+
return mockReadOwnerFromGitRemote;
26+
},
27+
}));
28+
29+
const mockReadTitleFromReadme = vi.fn();
30+
31+
vi.mock("./readTitleFromReadme.js", () => ({
32+
get readTitleFromReadme() {
33+
return mockReadTitleFromReadme;
34+
},
35+
}));
36+
37+
describe("getHydrationDefaults", () => {
38+
it("reads hydration defaults from existing readme and package json when exists", async () => {
39+
mockReadTitleFromReadme.mockResolvedValue("My Awesome Package");
40+
mockReadFileSafe.mockResolvedValueOnce(
41+
'{"author":"Someone <[email protected]>"}'
42+
);
43+
mockReadFundingIfExists.mockResolvedValue("Someone");
44+
mockReadOwnerFromGitRemote.mockResolvedValue("SUM1");
45+
46+
const result = await getHydrationDefaults();
47+
expect(await result.author()).toBe("Someone");
48+
expect(await result.email()).toBe("[email protected]");
49+
expect(await result.funding()).toBe("Someone");
50+
expect(await result.owner()).toBe("SUM1");
51+
expect(result.releases).toBe(true);
52+
expect(await result.title()).toBe("My Awesome Package");
53+
expect(result.unitTests).toBe(true);
54+
});
55+
});

src/hydrate/values/getHydrationDefaults.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import { readAuthorIfExists } from "./readAuthorIfExists.js";
55
import { readEmailIfExists } from "./readEmailIfExists.js";
66
import { readFundingIfExists } from "./readFundingIfExists.js";
77
import { readOwnerFromGitRemote } from "./readOwnerFromGitRemote.js";
8+
import { readTitleFromReadme } from "./readTitleFromReadme.js";
89

910
export async function getHydrationDefaults() {
10-
const existingReadme = await readFileSafe("./README.md", "");
1111
const existingPackage = JSON.parse(
1212
await readFileSafe("./package.json", "{}")
1313
) as PartialPackageData;
@@ -18,7 +18,7 @@ export async function getHydrationDefaults() {
1818
funding: readFundingIfExists,
1919
owner: readOwnerFromGitRemote,
2020
releases: true,
21-
title: existingReadme.match(/^(?:# |<h1\s+align="center">)(\S+)/)?.[1],
21+
title: readTitleFromReadme,
2222
unitTests: true,
2323
};
2424
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { describe, expect, it, vi } from "vitest";
2+
3+
import { readTitleFromReadme } from "./readTitleFromReadme.js";
4+
5+
const mockReadFileSafe = vi.fn();
6+
7+
vi.mock("../readFileSafe.js", () => ({
8+
get readFileSafe() {
9+
return mockReadFileSafe;
10+
},
11+
}));
12+
13+
describe("readTitleFromReadme", () => {
14+
it('reads title as markdown from "README.md" when it exists', async () => {
15+
mockReadFileSafe.mockResolvedValue("# My Awesome Package");
16+
const result = await readTitleFromReadme();
17+
expect(result).toBe("My Awesome Package");
18+
});
19+
20+
it('reads title as HTML from "README.md" when it exists', async () => {
21+
mockReadFileSafe.mockResolvedValue(
22+
'<h1 align="center">My Awesome Package</h1>'
23+
);
24+
const result = await readTitleFromReadme();
25+
expect(result).toBe("My Awesome Package");
26+
});
27+
28+
it("returns undefined when title does not exist", async () => {
29+
mockReadFileSafe.mockResolvedValue("");
30+
const result = await readTitleFromReadme();
31+
expect(result).toBe("");
32+
});
33+
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { readFileSafe } from "../readFileSafe.js";
2+
3+
export async function readTitleFromReadme() {
4+
return (
5+
(await readFileSafe("./README.md", ""))
6+
.match(/^(?:# |<h1\s+align="center">)(.*?)(?:<\/h1>)?$/i)?.[1]
7+
?.trim()
8+
.replace(/<[^>]+(?:>|$)/g, "") ?? ""
9+
);
10+
}

0 commit comments

Comments
 (0)