Skip to content

Commit 1217e12

Browse files
Fixed up logo detection, again
1 parent 3acc090 commit 1217e12

File tree

2 files changed

+65
-25
lines changed

2 files changed

+65
-25
lines changed

Diff for: src/shared/options/createOptionDefaults/readDefaultsFromReadme.test.ts

+61-22
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,17 @@ vi.mock("../../readFileSafe.js", () => ({
1313
describe("readDefaultsFromReadme", () => {
1414
describe("logo", () => {
1515
it("defaults to undefined when it cannot be found", async () => {
16-
mockReadFileSafe.mockResolvedValue("nothing.");
16+
mockReadFileSafe.mockResolvedValue(`
17+
nothing.
18+
`);
1719

1820
const logo = await readDefaultsFromReadme().logo();
1921

2022
expect(logo).toBeUndefined();
2123
});
2224

23-
it("parses when found after a badge image", async () => {
25+
it("parses when found in an unquoted string", async () => {
2426
mockReadFileSafe.mockResolvedValue(`
25-
<a href="#contributors" target="_blank"><img alt="👪 All Contributors: 48" src="https://img.shields.io/badge/%F0%9F%91%AA_all_contributors-48-21bb42.svg" /></a>
2627
<img src=abc/def.jpg/>
2728
`);
2829

@@ -34,8 +35,10 @@ describe("readDefaultsFromReadme", () => {
3435
});
3536
});
3637

37-
it("parses when found in an unquoted string", async () => {
38-
mockReadFileSafe.mockResolvedValue("<img src=abc/def.jpg/>");
38+
it("parses when found in a single quoted string", async () => {
39+
mockReadFileSafe.mockResolvedValue(`
40+
<img src='abc/def.jpg'/>
41+
`);
3942

4043
const logo = await readDefaultsFromReadme().logo();
4144

@@ -45,8 +48,10 @@ describe("readDefaultsFromReadme", () => {
4548
});
4649
});
4750

48-
it("parses when found in a single quoted string", async () => {
49-
mockReadFileSafe.mockResolvedValue("<img src='abc/def.jpg'/>");
51+
it("parses when found in a double quoted string", async () => {
52+
mockReadFileSafe.mockResolvedValue(`
53+
<img src="abc/def.jpg"/>
54+
`);
5055

5156
const logo = await readDefaultsFromReadme().logo();
5257

@@ -56,21 +61,23 @@ describe("readDefaultsFromReadme", () => {
5661
});
5762
});
5863

59-
it("parses when found in a double quoted string", async () => {
60-
mockReadFileSafe.mockResolvedValue('<img src="abc/def.jpg"/>');
64+
it("includes alt text when it exists in double quotes", async () => {
65+
mockReadFileSafe.mockResolvedValue(`
66+
<img alt="Project logo: a fancy circle" src="abc/def.jpg"/>
67+
`);
6168

6269
const logo = await readDefaultsFromReadme().logo();
6370

6471
expect(logo).toEqual({
65-
alt: "Project logo",
72+
alt: "Project logo: a fancy circle",
6673
src: "abc/def.jpg",
6774
});
6875
});
6976

70-
it("includes alt text when it exists in double quotes", async () => {
71-
mockReadFileSafe.mockResolvedValue(
72-
'<img alt="Project logo: a fancy circle" src="abc/def.jpg"/>',
73-
);
77+
it("includes alt text when it exists in single quotes", async () => {
78+
mockReadFileSafe.mockResolvedValue(`
79+
<img alt='Project logo: a fancy circle' src='abc/def.jpg'/>,
80+
`);
7481

7582
const logo = await readDefaultsFromReadme().logo();
7683

@@ -80,31 +87,63 @@ describe("readDefaultsFromReadme", () => {
8087
});
8188
});
8289

83-
it("includes alt text when it exists in single quotes", async () => {
84-
mockReadFileSafe.mockResolvedValue(
85-
"<img alt='Project logo: a fancy circle' src='abc/def.jpg'/>",
86-
);
90+
it("parses when found after a badge image", async () => {
91+
mockReadFileSafe.mockResolvedValue(`
92+
<a href="#contributors" target="_blank"><img alt="👪 All Contributors: 48" src="https://img.shields.io/badge/%F0%9F%91%AA_all_contributors-48-21bb42.svg" /></a>
93+
<img src=abc/def.jpg/>
94+
`);
8795

8896
const logo = await readDefaultsFromReadme().logo();
8997

9098
expect(logo).toEqual({
91-
alt: "Project logo: a fancy circle",
99+
alt: "Project logo",
92100
src: "abc/def.jpg",
93101
});
94102
});
103+
104+
it("parses when found after an h1 and many badge images", async () => {
105+
mockReadFileSafe.mockResolvedValue(`<h1 align="center">Create TypeScript App</h1>
106+
107+
<p align="center">Quickstart-friendly TypeScript template with comprehensive, configurable, opinionated tooling. 💝</p>
108+
109+
<p align="center">
110+
<!-- prettier-ignore-start -->
111+
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
112+
<a href="#contributors" target="_blank"><img alt="👪 All Contributors: 48" src="https://img.shields.io/badge/%F0%9F%91%AA_all_contributors-48-21bb42.svg" /></a>
113+
<!-- ALL-CONTRIBUTORS-BADGE:END -->
114+
<!-- prettier-ignore-end -->
115+
<a href="https://github.com/JoshuaKGoldberg/create-typescript-app/blob/main/.github/CODE_OF_CONDUCT.md" target="_blank"><img alt="🤝 Code of Conduct: Kept" src="https://img.shields.io/badge/%F0%9F%A4%9D_code_of_conduct-kept-21bb42" /></a>
116+
<a href="https://codecov.io/gh/JoshuaKGoldberg/create-typescript-app" target="_blank"><img alt="🧪 Coverage" src="https://img.shields.io/codecov/c/github/JoshuaKGoldberg/create-typescript-app?label=%F0%9F%A7%AA%20coverage" /></a>
117+
<a href="https://github.com/JoshuaKGoldberg/create-typescript-app/blob/main/LICENSE.md" target="_blank"><img alt="📝 License: MIT" src="https://img.shields.io/badge/%F0%9F%93%9D_license-MIT-21bb42.svg"></a>
118+
<a href="http://npmjs.com/package/create-typescript-app"><img alt="📦 npm version" src="https://img.shields.io/npm/v/create-typescript-app?color=21bb42&label=%F0%9F%93%A6%20npm" /></a>
119+
<img alt="💪 TypeScript: Strict" src="https://img.shields.io/badge/%F0%9F%92%AA_typescript-strict-21bb42.svg" />
120+
</p>
121+
122+
<img align="right" alt="Project logo: the TypeScript blue square with rounded corners, but a plus sign instead of 'TS'" src="./docs/create-typescript-app.png">
123+
`);
124+
125+
const logo = await readDefaultsFromReadme().logo();
126+
127+
expect(logo).toEqual({
128+
alt: "Project logo: the TypeScript blue square with rounded corners, but a plus sign instead of 'TS'",
129+
src: "./docs/create-typescript-app.png",
130+
});
131+
});
95132
});
96133

97134
describe("title", () => {
98135
it("defaults to undefined when it cannot be found", async () => {
99-
mockReadFileSafe.mockResolvedValue("nothing.");
136+
mockReadFileSafe.mockResolvedValue(`
137+
nothing.
138+
`);
100139

101140
const title = await readDefaultsFromReadme().title();
102141

103142
expect(title).toBeUndefined();
104143
});
105144

106145
it('reads title as markdown from "README.md" when it exists', async () => {
107-
mockReadFileSafe.mockResolvedValue("# My Awesome Package");
146+
mockReadFileSafe.mockResolvedValue(`# My Awesome Package`);
108147

109148
const title = await readDefaultsFromReadme().title();
110149

@@ -122,7 +161,7 @@ describe("readDefaultsFromReadme", () => {
122161
});
123162

124163
it("returns undefined when title does not exist", async () => {
125-
mockReadFileSafe.mockResolvedValue("");
164+
mockReadFileSafe.mockResolvedValue(`Other text.`);
126165

127166
const title = await readDefaultsFromReadme().title();
128167

Diff for: src/shared/options/createOptionDefaults/readDefaultsFromReadme.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,18 @@ export function readDefaultsFromReadme() {
66
const readme = lazyValue(async () => await readFileSafe("README.md", ""));
77

88
const imageTag = lazyValue(
9-
async () => /(?:^|\n)<img.+src.+\/>/.exec(await readme())?.[0],
9+
async () => /\n<img.+src=.+>/.exec(await readme())?.[0],
1010
);
1111

1212
return {
1313
logo: async () => {
1414
const tag = await imageTag();
15+
1516
if (!tag) {
1617
return undefined;
1718
}
1819

19-
const src = /src\s*=(.+)?\/>/
20+
const src = /src\s*=(.+)['"/]>/
2021
.exec(tag)?.[1]
2122
?.replaceAll(/^['"]|['"]$/g, "");
2223

@@ -25,7 +26,7 @@ export function readDefaultsFromReadme() {
2526
}
2627

2728
return {
28-
alt: /alt=['"](.+)['"] src=['"].+['"]/.exec(tag)?.[1] ?? "Project logo",
29+
alt: /alt=['"](.+)['"]\s*src=/.exec(tag)?.[1] ?? "Project logo",
2930
src,
3031
};
3132
},

0 commit comments

Comments
 (0)