|
| 1 | +import fs from "node:fs"; |
| 2 | +import os from "node:os"; |
1 | 3 | import path from "node:path"; |
2 | | -import { describe, expect, it } from "vitest"; |
| 4 | +import { afterAll, describe, expect, it } from "vitest"; |
3 | 5 | import { |
4 | 6 | discoverProject, |
| 7 | + discoverReactSubprojects, |
5 | 8 | formatFrameworkName, |
6 | 9 | listWorkspacePackages, |
7 | 10 | } from "../src/utils/discover-project.js"; |
@@ -46,6 +49,69 @@ describe("listWorkspacePackages", () => { |
46 | 49 | }); |
47 | 50 | }); |
48 | 51 |
|
| 52 | +const tempDirectory = fs.mkdtempSync(path.join(os.tmpdir(), "react-doctor-discover-test-")); |
| 53 | + |
| 54 | +afterAll(() => { |
| 55 | + fs.rmSync(tempDirectory, { recursive: true, force: true }); |
| 56 | +}); |
| 57 | + |
| 58 | +describe("discoverReactSubprojects", () => { |
| 59 | + it("includes root directory when it has a react dependency", () => { |
| 60 | + const rootDirectory = path.join(tempDirectory, "root-with-react"); |
| 61 | + fs.mkdirSync(rootDirectory, { recursive: true }); |
| 62 | + fs.writeFileSync( |
| 63 | + path.join(rootDirectory, "package.json"), |
| 64 | + JSON.stringify({ name: "my-app", dependencies: { react: "^19.0.0" } }), |
| 65 | + ); |
| 66 | + |
| 67 | + const packages = discoverReactSubprojects(rootDirectory); |
| 68 | + expect(packages).toContainEqual({ name: "my-app", directory: rootDirectory }); |
| 69 | + }); |
| 70 | + |
| 71 | + it("includes both root and subdirectory when both have react", () => { |
| 72 | + const rootDirectory = path.join(tempDirectory, "root-and-sub"); |
| 73 | + const subdirectory = path.join(rootDirectory, "extension"); |
| 74 | + fs.mkdirSync(subdirectory, { recursive: true }); |
| 75 | + fs.writeFileSync( |
| 76 | + path.join(rootDirectory, "package.json"), |
| 77 | + JSON.stringify({ name: "my-app", dependencies: { react: "^19.0.0" } }), |
| 78 | + ); |
| 79 | + fs.writeFileSync( |
| 80 | + path.join(subdirectory, "package.json"), |
| 81 | + JSON.stringify({ name: "my-extension", dependencies: { react: "^18.0.0" } }), |
| 82 | + ); |
| 83 | + |
| 84 | + const packages = discoverReactSubprojects(rootDirectory); |
| 85 | + expect(packages).toHaveLength(2); |
| 86 | + expect(packages[0]).toEqual({ name: "my-app", directory: rootDirectory }); |
| 87 | + expect(packages[1]).toEqual({ name: "my-extension", directory: subdirectory }); |
| 88 | + }); |
| 89 | + |
| 90 | + it("does not match packages with only @types/react", () => { |
| 91 | + const rootDirectory = path.join(tempDirectory, "types-only"); |
| 92 | + fs.mkdirSync(rootDirectory, { recursive: true }); |
| 93 | + fs.writeFileSync( |
| 94 | + path.join(rootDirectory, "package.json"), |
| 95 | + JSON.stringify({ name: "types-only", devDependencies: { "@types/react": "^18.0.0" } }), |
| 96 | + ); |
| 97 | + |
| 98 | + const packages = discoverReactSubprojects(rootDirectory); |
| 99 | + expect(packages).toHaveLength(0); |
| 100 | + }); |
| 101 | + |
| 102 | + it("matches packages with react-native dependency", () => { |
| 103 | + const rootDirectory = path.join(tempDirectory, "rn-app"); |
| 104 | + fs.mkdirSync(rootDirectory, { recursive: true }); |
| 105 | + fs.writeFileSync( |
| 106 | + path.join(rootDirectory, "package.json"), |
| 107 | + JSON.stringify({ name: "rn-app", dependencies: { "react-native": "^0.74.0" } }), |
| 108 | + ); |
| 109 | + |
| 110 | + const packages = discoverReactSubprojects(rootDirectory); |
| 111 | + expect(packages).toHaveLength(1); |
| 112 | + }); |
| 113 | +}); |
| 114 | + |
49 | 115 | describe("formatFrameworkName", () => { |
50 | 116 | it("formats known frameworks", () => { |
51 | 117 | expect(formatFrameworkName("nextjs")).toBe("Next.js"); |
|
0 commit comments